github.com/aclaygray/packer@v1.3.2/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 - `only_on` (array of strings) - This is an array of 95 [runtime operating systems](https://golang.org/doc/install/source#environment) 96 where `shell-local` will execute. This allows you to execute `shell-local` 97 *only* on specific operating systems. By default, shell-local will always run 98 if `only_on` is not set." 99 100 - `use_linux_pathing` (bool) - This is only relevant to windows hosts. If you 101 are running Packer in a Windows environment with the Windows Subsystem for 102 Linux feature enabled, and would like to invoke a bash script rather than 103 invoking a Cmd script, you'll need to set this flag to true; it tells Packer 104 to use the linux subsystem path for your script rather than the Windows path. 105 (e.g. /mnt/c/path/to/your/file instead of C:/path/to/your/file). Please see 106 the example below for more guidance on how to use this feature. If you are 107 not on a Windows host, or you do not intend to use the shell-local 108 post-processor to run a bash script, please ignore this option. 109 If you set this flag to true, you still need to provide the standard windows 110 path to the script when providing a `script`. This is a beta feature. 111 112 ## Execute Command 113 114 To many new users, the `execute_command` is puzzling. However, it provides an 115 important function: customization of how the command is executed. The most 116 common use case for this is dealing with **sudo password prompts**. You may also 117 need to customize this if you use a non-POSIX shell, such as `tcsh` on FreeBSD. 118 119 ### The Windows Linux Subsystem 120 121 The shell-local post-processor was designed with the idea of allowing you to run 122 commands in your local operating system's native shell. For Windows, we've 123 assumed in our defaults that this is Cmd. However, it is possible to run a 124 bash script as part of the Windows Linux Subsystem from the shell-local 125 post-processor, by modifying the `execute_command` and the `use_linux_pathing` 126 options in the post-processor config. 127 128 The example below is a fully functional test config. 129 130 One limitation of this offering is that "inline" and "command" options are not 131 available to you; please limit yourself to using the "script" or "scripts" 132 options instead. 133 134 Please note that this feature is still in beta, as the underlying WSL is also 135 still in beta. There will be some limitations as a result. For example, it will 136 likely not work unless both Packer and the scripts you want to run are both on 137 the C drive. 138 139 ``` 140 { 141 "builders": [ 142 { 143 "type": "null", 144 "communicator": "none" 145 } 146 ], 147 "provisioners": [ 148 { 149 "type": "shell-local", 150 "environment_vars": ["PROVISIONERTEST=ProvisionerTest1"], 151 "execute_command": ["bash", "-c", "{{.Vars}} {{.Script}}"], 152 "use_linux_pathing": true, 153 "scripts": ["C:/Users/me/scripts/example_bash.sh"] 154 }, 155 { 156 "type": "shell-local", 157 "environment_vars": ["PROVISIONERTEST=ProvisionerTest2"], 158 "execute_command": ["bash", "-c", "{{.Vars}} {{.Script}}"], 159 "use_linux_pathing": true, 160 "script": "C:/Users/me/scripts/example_bash.sh" 161 } 162 ] 163 } 164 ``` 165 166 ## Default Environmental Variables 167 168 In addition to being able to specify custom environmental variables using the 169 `environment_vars` configuration, the provisioner automatically defines certain 170 commonly useful environmental variables: 171 172 - `PACKER_BUILD_NAME` is set to the 173 [name of the build](/docs/templates/builders.html#named-builds) that Packer is running. 174 This is most useful when Packer is making multiple builds and you want to 175 distinguish them slightly from a common provisioning script. 176 177 - `PACKER_BUILDER_TYPE` is the type of the builder that was used to create the 178 machine that the script is running on. This is useful if you want to run 179 only certain parts of the script on systems built with certain builders. 180 181 ## Safely Writing A Script 182 183 Whether you use the `inline` option, or pass it a direct `script` or `scripts`, 184 it is important to understand a few things about how the shell-local 185 post-processor works to run it safely and easily. This understanding will save 186 you much time in the process. 187 188 ### Once Per Builder 189 190 The `shell-local` script(s) you pass are run once per builder. That means that 191 if you have an `amazon-ebs` builder and a `docker` builder, your script will be 192 run twice. If you have 3 builders, it will run 3 times, once for each builder. 193 194 ### Interacting with Build Artifacts 195 196 In order to interact with build artifacts, you may want to use the [manifest 197 post-processor](/docs/post-processors/manifest.html). This will write the list 198 of files produced by a `builder` to a json file after each `builder` is run. 199 200 For example, if you wanted to package a file from the file builder into a 201 tarball, you might write this: 202 203 ``` json 204 { 205 "builders": [ 206 { 207 "content": "Lorem ipsum dolor sit amet", 208 "target": "dummy_artifact", 209 "type": "file" 210 } 211 ], 212 "post-processors": [ 213 [ 214 { 215 "output": "manifest.json", 216 "strip_path": true, 217 "type": "manifest" 218 }, 219 { 220 "inline": [ 221 "jq \".builds[].files[].name\" manifest.json | xargs tar cfz artifacts.tgz" 222 ], 223 "type": "shell-local" 224 } 225 ] 226 ] 227 } 228 ``` 229 230 This uses the [jq](https://stedolan.github.io/jq/) tool to extract all of the 231 file names from the manifest file and passes them to tar. 232 233 ### Always Exit Intentionally 234 235 If any post-processor fails, the `packer build` stops and all interim artifacts 236 are cleaned up. 237 238 For a shell script, that means the script **must** exit with a zero code. You 239 *must* be extra careful to `exit 0` when necessary. 240 241 242 ## Usage Examples: 243 244 Example of running a .cmd file on windows: 245 246 ``` 247 { 248 "type": "shell-local", 249 "environment_vars": ["SHELLLOCALTEST=ShellTest1"], 250 "scripts": ["./scripts/test_cmd.cmd"] 251 }, 252 ``` 253 254 Contents of "test_cmd.cmd": 255 256 ``` 257 echo %SHELLLOCALTEST% 258 ``` 259 260 Example of running an inline command on windows: 261 Required customization: tempfile_extension 262 263 ``` 264 { 265 "type": "shell-local", 266 "environment_vars": ["SHELLLOCALTEST=ShellTest2"], 267 "tempfile_extension": ".cmd", 268 "inline": ["echo %SHELLLOCALTEST%"] 269 }, 270 ``` 271 272 Example of running a bash command on windows using WSL: 273 Required customizations: use_linux_pathing and execute_command 274 275 ``` 276 { 277 "type": "shell-local", 278 "environment_vars": ["SHELLLOCALTEST=ShellTest3"], 279 "execute_command": ["bash", "-c", "{{.Vars}} {{.Script}}"], 280 "use_linux_pathing": true, 281 "script": "./scripts/example_bash.sh" 282 } 283 ``` 284 285 Contents of "example_bash.sh": 286 287 ``` 288 #!/bin/bash 289 echo $SHELLLOCALTEST 290 ``` 291 292 Example of running a powershell script on windows: 293 Required customizations: env_var_format and execute_command 294 295 ``` 296 297 { 298 "type": "shell-local", 299 "environment_vars": ["SHELLLOCALTEST=ShellTest4"], 300 "execute_command": ["powershell.exe", "{{.Vars}} {{.Script}}"], 301 "env_var_format": "$env:%s=\"%s\"; ", 302 "script": "./scripts/example_ps.ps1" 303 } 304 ``` 305 306 Example of running a powershell script on windows as "inline": 307 Required customizations: env_var_format, tempfile_extension, and execute_command 308 309 ``` 310 { 311 "type": "shell-local", 312 "tempfile_extension": ".ps1", 313 "environment_vars": ["SHELLLOCALTEST=ShellTest5"], 314 "execute_command": ["powershell.exe", "{{.Vars}} {{.Script}}"], 315 "env_var_format": "$env:%s=\"%s\"; ", 316 "inline": ["write-output $env:SHELLLOCALTEST"] 317 } 318 ``` 319 320 321 Example of running a bash script on linux: 322 323 ``` 324 { 325 "type": "shell-local", 326 "environment_vars": ["PROVISIONERTEST=ProvisionerTest1"], 327 "scripts": ["./scripts/example_bash.sh"] 328 } 329 ``` 330 331 Example of running a bash "inline" on linux: 332 333 ``` 334 { 335 "type": "shell-local", 336 "environment_vars": ["PROVISIONERTEST=ProvisionerTest2"], 337 "inline": ["echo hello", 338 "echo $PROVISIONERTEST"] 339 } 340 ``` 341 342