github.com/StackPointCloud/packer@v0.10.2-0.20180716202532-b28098e0f79b/website/source/docs/post-processors/shell-local.html.md (about) 1 --- 2 description: | 3 The shell-local Packer post processor enables users to do some post processing 4 after artifacts have been built. 5 layout: docs 6 page_title: 'Local Shell - Post-Processors' 7 sidebar_current: 'docs-post-processors-shell-local' 8 --- 9 10 # Local Shell Post Processor 11 12 Type: `shell-local` 13 14 The local shell post processor executes scripts locally during the post 15 processing stage. Shell local provides a convenient way to automate executing 16 some task with packer outputs and variables. 17 18 ## Basic example 19 20 The example below is fully functional. 21 22 ``` json 23 { 24 "type": "shell-local", 25 "inline": ["echo foo"] 26 } 27 ``` 28 29 ## Configuration Reference 30 31 The reference of available configuration options is listed below. The only 32 required element is either "inline" or "script". Every other option is optional. 33 34 Exactly *one* of the following is required: 35 36 - `command` (string) - This is a single command to execute. It will be written 37 to a temporary file and run using the `execute_command` call below. 38 39 - `inline` (array of strings) - This is an array of commands to execute. The 40 commands are concatenated by newlines and turned into a single file, so they 41 are all executed within the same context. This allows you to change 42 directories in one command and use something in the directory in the next 43 and so on. Inline scripts are the easiest way to pull off simple tasks 44 within the machine. 45 46 - `script` (string) - The path to a script to execute. This path can be 47 absolute or relative. If it is relative, it is relative to the working 48 directory when Packer is executed. 49 50 - `scripts` (array of strings) - An array of scripts to execute. The scripts 51 will be executed in the order specified. Each script is executed in 52 isolation, so state such as variables from one script won't carry on to the 53 next. 54 55 Optional parameters: 56 57 - `environment_vars` (array of strings) - An array of key/value pairs to 58 inject prior to the `execute_command`. The format should be `key=value`. 59 Packer injects some environmental variables by default into the environment, 60 as well, which are covered in the section below. 61 62 - `execute_command` (array of strings) - The command used to execute the script. By 63 default this is `["/bin/sh", "-c", "{{.Vars}}, "{{.Script}}"]` 64 on unix and `["cmd", "/c", "{{.Vars}}", "{{.Script}}"]` on windows. 65 This is treated as a [template engine](/docs/templates/engine.html). 66 There are two available variables: `Script`, which is the path to the script 67 to run, and `Vars`, which is the list of `environment_vars`, if configured. 68 If you choose to set this option, make sure that the first element in the 69 array is the shell program you want to use (for example, "sh" or 70 "/usr/local/bin/zsh" or even "powershell.exe" although anything other than 71 a flavor of the shell command language is not explicitly supported and may 72 be broken by assumptions made within Packer). It's worth noting that if you 73 choose to try to use shell-local for Powershell or other Windows commands, 74 the environment variables will not be set properly for your environment. 75 76 For backwards compatibility, `execute_command` will accept a string instead 77 of an array of strings. If a single string or an array of strings with only 78 one element is provided, Packer will replicate past behavior by appending 79 your `execute_command` to the array of strings `["sh", "-c"]`. For example, 80 if you set `"execute_command": "foo bar"`, the final `execute_command` that 81 Packer runs will be ["sh", "-c", "foo bar"]. If you set `"execute_command": ["foo", "bar"]`, 82 the final execute_command will remain `["foo", "bar"]`. 83 84 Again, the above is only provided as a backwards compatibility fix; we 85 strongly recommend that you set execute_command as an array of strings. 86 87 - `inline_shebang` (string) - The 88 [shebang](http://en.wikipedia.org/wiki/Shebang_%28Unix%29) value to use when 89 running commands specified by `inline`. By default, this is `/bin/sh -e`. If 90 you're not using `inline`, then this configuration has no effect. 91 **Important:** If you customize this, be sure to include something like the 92 `-e` flag, otherwise individual steps failing won't fail the provisioner. 93 94 - `use_linux_pathing` (bool) - This is only relevant to windows hosts. If you 95 are running Packer in a Windows environment with the Windows Subsystem for 96 Linux feature enabled, and would like to invoke a bash script rather than 97 invoking a Cmd script, you'll need to set this flag to true; it tells Packer 98 to use the linux subsystem path for your script rather than the Windows path. 99 (e.g. /mnt/c/path/to/your/file instead of C:/path/to/your/file). Please see 100 the example below for more guidance on how to use this feature. If you are 101 not on a Windows host, or you do not intend to use the shell-local 102 post-processor to run a bash script, please ignore this option. 103 If you set this flag to true, you still need to provide the standard windows 104 path to the script when providing a `script`. This is a beta feature. 105 106 ## Execute Command 107 108 To many new users, the `execute_command` is puzzling. However, it provides an 109 important function: customization of how the command is executed. The most 110 common use case for this is dealing with **sudo password prompts**. You may also 111 need to customize this if you use a non-POSIX shell, such as `tcsh` on FreeBSD. 112 113 ### The Windows Linux Subsystem 114 115 The shell-local post-processor was designed with the idea of allowing you to run 116 commands in your local operating system's native shell. For Windows, we've 117 assumed in our defaults that this is Cmd. However, it is possible to run a 118 bash script as part of the Windows Linux Subsystem from the shell-local 119 post-processor, by modifying the `execute_command` and the `use_linux_pathing` 120 options in the post-processor config. 121 122 The example below is a fully functional test config. 123 124 One limitation of this offering is that "inline" and "command" options are not 125 available to you; please limit yourself to using the "script" or "scripts" 126 options instead. 127 128 Please note that this feature is still in beta, as the underlying WSL is also 129 still in beta. There will be some limitations as a result. For example, it will 130 likely not work unless both Packer and the scripts you want to run are both on 131 the C drive. 132 133 ``` 134 { 135 "builders": [ 136 { 137 "type": "null", 138 "communicator": "none" 139 } 140 ], 141 "provisioners": [ 142 { 143 "type": "shell-local", 144 "environment_vars": ["PROVISIONERTEST=ProvisionerTest1"], 145 "execute_command": ["bash", "-c", "{{.Vars}} {{.Script}}"], 146 "use_linux_pathing": true, 147 "scripts": ["C:/Users/me/scripts/example_bash.sh"] 148 }, 149 { 150 "type": "shell-local", 151 "environment_vars": ["PROVISIONERTEST=ProvisionerTest2"], 152 "execute_command": ["bash", "-c", "{{.Vars}} {{.Script}}"], 153 "use_linux_pathing": true, 154 "script": "C:/Users/me/scripts/example_bash.sh" 155 } 156 ] 157 } 158 ``` 159 160 ## Default Environmental Variables 161 162 In addition to being able to specify custom environmental variables using the 163 `environment_vars` configuration, the provisioner automatically defines certain 164 commonly useful environmental variables: 165 166 - `PACKER_BUILD_NAME` is set to the 167 [name of the build](/docs/templates/builders.html#named-builds) that Packer is running. 168 This is most useful when Packer is making multiple builds and you want to 169 distinguish them slightly from a common provisioning script. 170 171 - `PACKER_BUILDER_TYPE` is the type of the builder that was used to create the 172 machine that the script is running on. This is useful if you want to run 173 only certain parts of the script on systems built with certain builders. 174 175 ## Safely Writing A Script 176 177 Whether you use the `inline` option, or pass it a direct `script` or `scripts`, 178 it is important to understand a few things about how the shell-local 179 post-processor works to run it safely and easily. This understanding will save 180 you much time in the process. 181 182 ### Once Per Builder 183 184 The `shell-local` script(s) you pass are run once per builder. That means that 185 if you have an `amazon-ebs` builder and a `docker` builder, your script will be 186 run twice. If you have 3 builders, it will run 3 times, once for each builder. 187 188 ### Interacting with Build Artifacts 189 190 In order to interact with build artifacts, you may want to use the [manifest 191 post-processor](/docs/post-processors/manifest.html). This will write the list 192 of files produced by a `builder` to a json file after each `builder` is run. 193 194 For example, if you wanted to package a file from the file builder into 195 a tarball, you might wright this: 196 197 ``` json 198 { 199 "builders": [ 200 { 201 "content": "Lorem ipsum dolor sit amet", 202 "target": "dummy_artifact", 203 "type": "file" 204 } 205 ], 206 "post-processors": [ 207 [ 208 { 209 "output": "manifest.json", 210 "strip_path": true, 211 "type": "manifest" 212 }, 213 { 214 "inline": [ 215 "jq \".builds[].files[].name\" manifest.json | xargs tar cfz artifacts.tgz" 216 ], 217 "type": "shell-local" 218 } 219 ] 220 ] 221 } 222 ``` 223 224 This uses the [jq](https://stedolan.github.io/jq/) tool to extract all of the 225 file names from the manifest file and passes them to tar. 226 227 ### Always Exit Intentionally 228 229 If any post-processor fails, the `packer build` stops and all interim artifacts 230 are cleaned up. 231 232 For a shell script, that means the script **must** exit with a zero code. You 233 *must* be extra careful to `exit 0` when necessary. 234 235 236 ## Usage Examples: 237 238 Example of running a .cmd file on windows: 239 240 ``` 241 { 242 "type": "shell-local", 243 "environment_vars": ["SHELLLOCALTEST=ShellTest1"], 244 "scripts": ["./scripts/test_cmd.cmd"] 245 }, 246 ``` 247 248 Contents of "test_cmd.cmd": 249 250 ``` 251 echo %SHELLLOCALTEST% 252 ``` 253 254 Example of running an inline command on windows: 255 Required customization: tempfile_extension 256 257 ``` 258 { 259 "type": "shell-local", 260 "environment_vars": ["SHELLLOCALTEST=ShellTest2"], 261 "tempfile_extension": ".cmd", 262 "inline": ["echo %SHELLLOCALTEST%"] 263 }, 264 ``` 265 266 Example of running a bash command on windows using WSL: 267 Required customizations: use_linux_pathing and execute_command 268 269 ``` 270 { 271 "type": "shell-local", 272 "environment_vars": ["SHELLLOCALTEST=ShellTest3"], 273 "execute_command": ["bash", "-c", "{{.Vars}} {{.Script}}"], 274 "use_linux_pathing": true, 275 "script": "./scripts/example_bash.sh" 276 } 277 ``` 278 279 Contents of "example_bash.sh": 280 281 ``` 282 #!/bin/bash 283 echo $SHELLLOCALTEST 284 ``` 285 286 Example of running a powershell script on windows: 287 Required customizations: env_var_format and execute_command 288 289 ``` 290 291 { 292 "type": "shell-local", 293 "environment_vars": ["SHELLLOCALTEST=ShellTest4"], 294 "execute_command": ["powershell.exe", "{{.Vars}} {{.Script}}"], 295 "env_var_format": "$env:%s=\"%s\"; ", 296 "script": "./scripts/example_ps.ps1" 297 } 298 ``` 299 300 Example of running a powershell script on windows as "inline": 301 Required customizations: env_var_format, tempfile_extension, and execute_command 302 303 ``` 304 { 305 "type": "shell-local", 306 "tempfile_extension": ".ps1", 307 "environment_vars": ["SHELLLOCALTEST=ShellTest5"], 308 "execute_command": ["powershell.exe", "{{.Vars}} {{.Script}}"], 309 "env_var_format": "$env:%s=\"%s\"; ", 310 "inline": ["write-output $env:SHELLLOCALTEST"] 311 } 312 ``` 313 314 315 Example of running a bash script on linux: 316 317 ``` 318 { 319 "type": "shell-local", 320 "environment_vars": ["PROVISIONERTEST=ProvisionerTest1"], 321 "scripts": ["./scripts/example_bash.sh"] 322 } 323 ``` 324 325 Example of running a bash "inline" on linux: 326 327 ``` 328 { 329 "type": "shell-local", 330 "environment_vars": ["PROVISIONERTEST=ProvisionerTest2"], 331 "inline": ["echo hello", 332 "echo $PROVISIONERTEST"] 333 } 334 ``` 335 336