github.com/aspring/packer@v0.8.1-0.20150629211158-9db281ac0f89/website/source/docs/extend/provisioner.html.markdown (about) 1 --- 2 layout: "docs" 3 page_title: "Custom Provisioner Development" 4 description: |- 5 Packer Provisioners are the components of Packer that install and configure software into a running machine prior to turning that machine into an image. An example of a provisioner is the shell provisioner, which runs shell scripts within the machines. 6 --- 7 8 # Custom Provisioner Development 9 10 Packer Provisioners are the components of Packer that install and configure 11 software into a running machine prior to turning that machine into an 12 image. An example of a provisioner is the [shell provisioner](/docs/provisioners/shell.html), 13 which runs shell scripts within the machines. 14 15 Prior to reading this page, it is assumed you have read the page on 16 [plugin development basics](/docs/extend/developing-plugins.html). 17 18 Provisioner plugins implement the `packer.Provisioner` interface and 19 are served using the `plugin.ServeProvisioner` function. 20 21 ~> **Warning!** This is an advanced topic. If you're new to Packer, we 22 recommend getting a bit more comfortable before you dive into writing plugins. 23 24 ## The Interface 25 26 The interface that must be implemented for a provisioner is the 27 `packer.Provisioner` interface. It is reproduced below for easy reference. 28 The actual interface in the source code contains some basic documentation as well explaining 29 what each method should do. 30 31 ```go 32 type Provisioner interface { 33 Prepare(...interface{}) error 34 Provision(Ui, Communicator) error 35 } 36 ``` 37 38 ### The "Prepare" Method 39 40 The `Prepare` method for each provisioner is called prior to any runs with 41 the configuration that was given in the template. This is passed in as 42 an array of `interface{}` types, but is generally `map[string]interface{}`. The prepare 43 method is responsible for translating this configuration into an internal 44 structure, validating it, and returning any errors. 45 46 For multiple parameters, they should be merged together into the final 47 configuration, with later parameters overwriting any previous configuration. 48 The exact semantics of the merge are left to the builder author. 49 50 For decoding the `interface{}` into a meaningful structure, the 51 [mapstructure](https://github.com/mitchellh/mapstructure) library is recommended. 52 Mapstructure will take an `interface{}` and decode it into an arbitrarily 53 complex struct. If there are any errors, it generates very human friendly 54 errors that can be returned directly from the prepare method. 55 56 While it is not actively enforced, **no side effects** should occur from 57 running the `Prepare` method. Specifically, don't create files, don't launch 58 virtual machines, etc. Prepare's purpose is solely to configure the builder 59 and validate the configuration. 60 61 The `Prepare` method is called very early in the build process so that 62 errors may be displayed to the user before anything actually happens. 63 64 ### The "Provision" Method 65 66 The `Provision` method is called when a machine is running and ready 67 to be provisioned. The provisioner should do its real work here. 68 69 The method takes two parameters: a `packer.Ui` and a `packer.Communicator`. 70 The UI can be used to communicate with the user what is going on. The 71 communicator is used to communicate with the running machine, and is 72 guaranteed to be connected at this point. 73 74 The provision method should not return until provisioning is complete. 75 76 ## Using the Communicator 77 78 The `packer.Communicator` parameter and interface is used to communicate 79 with running machine. The machine may be local (in a virtual machine or 80 container of some sort) or it may be remote (in a cloud). The communicator 81 interface abstracts this away so that communication is the same overall. 82 83 The documentation around the [code itself](https://github.com/mitchellh/packer/blob/master/packer/communicator.go) 84 is really great as an overview of how to use the interface. You should begin 85 by reading this. Once you have read it, you can see some example usage below: 86 87 ```go 88 // Build the remote command. 89 var cmd packer.RemoteCmd 90 cmd.Command = "echo foo" 91 92 // We care about stdout, so lets collect that into a buffer. Since 93 // we don't set stderr, that will just be discarded. 94 var stdout bytes.Buffer 95 cmd.Stdout = &stdout 96 97 // Start the command 98 if err := comm.Start(&cmd); err != nil { 99 panic(err) 100 } 101 102 // Wait for it to complete 103 cmd.Wait() 104 105 // Read the stdout! 106 fmt.Printf("Command output: %s", stdout.String()) 107 ```