github.com/ratanraj/packer@v1.3.2/website/source/docs/provisioners/shell.html.md (about)

     1  ---
     2  description: |
     3      The shell Packer provisioner provisions machines built by Packer using shell
     4      scripts. Shell provisioning is the easiest way to get software installed and
     5      configured on a machine.
     6  layout: docs
     7  page_title: 'Shell - Provisioners'
     8  sidebar_current: 'docs-provisioners-shell-remote'
     9  ---
    10  
    11  # Shell Provisioner
    12  
    13  Type: `shell`
    14  
    15  The shell Packer provisioner provisions machines built by Packer using shell
    16  scripts. Shell provisioning is the easiest way to get software installed and
    17  configured on a machine.
    18  
    19  -> **Building Windows images?** You probably want to use the
    20  [PowerShell](/docs/provisioners/powershell.html) or [Windows
    21  Shell](/docs/provisioners/windows-shell.html) provisioners.
    22  
    23  ## Basic Example
    24  
    25  The example below is fully functional.
    26  
    27  ``` json
    28  {
    29    "type": "shell",
    30    "inline": ["echo foo"]
    31  }
    32  ```
    33  
    34  ## Configuration Reference
    35  
    36  The reference of available configuration options is listed below. The only
    37  required element is either "inline" or "script". Every other option is optional.
    38  
    39  Exactly *one* of the following is required:
    40  
    41  -   `inline` (array of strings) - This is an array of commands to execute. The
    42      commands are concatenated by newlines and turned into a single file, so they
    43      are all executed within the same context. This allows you to change
    44      directories in one command and use something in the directory in the next
    45      and so on. Inline scripts are the easiest way to pull off simple tasks
    46      within the machine.
    47  
    48  -   `script` (string) - The path to a script to upload and execute in
    49      the machine. This path can be absolute or relative. If it is relative, it is
    50      relative to the working directory when Packer is executed.
    51  
    52  -   `scripts` (array of strings) - An array of scripts to execute. The scripts
    53      will be uploaded and executed in the order specified. Each script is
    54      executed in isolation, so state such as variables from one script won't
    55      carry on to the next.
    56  
    57  Optional parameters:
    58  
    59  -   `binary` (boolean) - If true, specifies that the script(s) are binary files,
    60      and Packer should therefore not convert Windows line endings to Unix line
    61      endings (if there are any). By default this is false.
    62  
    63  -   `environment_vars` (array of strings) - An array of key/value pairs to
    64      inject prior to the execute\_command. The format should be `key=value`.
    65      Packer injects some environmental variables by default into the environment,
    66      as well, which are covered in the section below.
    67  
    68  -   `use_env_var_file` (boolean) - If true, Packer will write your environment
    69      variables to a tempfile and source them from that file, rather than
    70      declaring them inline in our execute_command. The default `execute_command`
    71      will be `chmod +x {{.Path}}; . {{.EnvVarFile}} && {{.Path}}`. This option is
    72      unnecessary for most cases, but if you have extra quoting in your custom
    73      `execute_command`, then this may be unnecessary for proper script execution.
    74      Default: false.
    75  
    76  -   `execute_command` (string) - The command to use to execute the script. By
    77      default this is `chmod +x {{ .Path }}; {{ .Vars }} {{ .Path }}`, unless the
    78      user has set `"use_env_var_file": true` -- in that case, the default
    79      `execute_command` is `chmod +x {{.Path}}; . {{.EnvVarFile}} && {{.Path}}`.
    80      The value of this is treated as a
    81      [configuration template](/docs/templates/engine.html). There are three
    82      available variables:
    83        *  `Path` is the path to the script to run
    84        *  `Vars` is the list of `environment_vars`, if configured.
    85        *  `EnvVarFile` is the path to the file containing env vars, if
    86              `use_env_var_file` is true.
    87  -   `expect_disconnect` (boolean) - Defaults to `false`. Whether to error if the
    88      server disconnects us. A disconnect might happen if you restart the ssh
    89      server or reboot the host.
    90  
    91  -   `inline_shebang` (string) - The
    92      [shebang](https://en.wikipedia.org/wiki/Shebang_%28Unix%29) value to use when
    93      running commands specified by `inline`. By default, this is `/bin/sh -e`. If
    94      you're not using `inline`, then this configuration has no effect.
    95      **Important:** If you customize this, be sure to include something like the
    96      `-e` flag, otherwise individual steps failing won't fail the provisioner.
    97  
    98  -   `remote_folder` (string) - The folder where the uploaded script will reside on
    99      the machine. This defaults to '/tmp'.
   100  
   101  -   `remote_file` (string) - The filename the uploaded script will have on the machine.
   102      This defaults to 'script\_nnn.sh'.
   103  
   104  -   `remote_path` (string) - The full path to the uploaded script will have on the
   105      machine. By default this is remote\_folder/remote\_file, if set this option will
   106      override both remote\_folder and remote\_file.
   107  
   108  -   `skip_clean` (boolean) - If true, specifies that the helper scripts
   109      uploaded to the system will not be removed by Packer. This defaults to
   110      false (clean scripts from the system).
   111  
   112  -   `start_retry_timeout` (string) - The amount of time to attempt to *start*
   113      the remote process. By default this is `5m` or 5 minutes. This setting
   114      exists in order to deal with times when SSH may restart, such as a
   115      system reboot. Set this to a higher value if reboots take a longer amount
   116      of time.
   117  
   118  ## Execute Command Example
   119  
   120  To many new users, the `execute_command` is puzzling. However, it provides an
   121  important function: customization of how the command is executed. The most
   122  common use case for this is dealing with **sudo password prompts**. You may also
   123  need to customize this if you use a non-POSIX shell, such as `tcsh` on FreeBSD.
   124  
   125  ### Sudo Example
   126  
   127  Some operating systems default to a non-root user. For example if you login as
   128  `ubuntu` and can sudo using the password `packer`, then you'll want to change
   129  `execute_command` to be:
   130  
   131  ``` text
   132  "echo 'packer' | sudo -S sh -c '{{ .Vars }} {{ .Path }}'"
   133  ```
   134  
   135  The `-S` flag tells `sudo` to read the password from stdin, which in this case
   136  is being piped in with the value of `packer`.
   137  
   138  The above example won't work if your environment vars contain spaces or single quotes; in these cases try removing the single quotes:
   139  
   140  ``` text
   141  "echo 'packer' | sudo -S env {{ .Vars }} {{ .Path }}"
   142  ```
   143  
   144  By setting the `execute_command` to this, your script(s) can run with root
   145  privileges without worrying about password prompts.
   146  
   147  ### FreeBSD Example
   148  
   149  FreeBSD's default shell is `tcsh`, which deviates from POSIX semantics. In order
   150  for packer to pass environment variables you will need to change the
   151  `execute_command` to:
   152  
   153  ``` text
   154  chmod +x {{ .Path }}; env {{ .Vars }} {{ .Path }}
   155  ```
   156  
   157  Note the addition of `env` before `{{ .Vars }}`.
   158  
   159  ## Default Environmental Variables
   160  
   161  In addition to being able to specify custom environmental variables using the
   162  `environment_vars` configuration, the provisioner automatically defines certain
   163  commonly useful environmental variables:
   164  
   165  -   `PACKER_BUILD_NAME` is set to the
   166      [name of the build](/docs/templates/builders.html#named-builds) that Packer is running.
   167      This is most useful when Packer is making multiple builds and you want to
   168      distinguish them slightly from a common provisioning script.
   169  
   170  -   `PACKER_BUILDER_TYPE` is the type of the builder that was used to create the
   171      machine that the script is running on. This is useful if you want to run
   172      only certain parts of the script on systems built with certain builders.
   173  
   174  -   `PACKER_HTTP_ADDR` If using a builder that provides an http server for file
   175      transfer (such as hyperv, parallels, qemu, virtualbox, and vmware), this
   176      will be set to the address. You can use this address in your provisioner to
   177      download large files over http. This may be useful if you're experiencing
   178      slower speeds using the default file provisioner. A file provisioner using
   179      the `winrm` communicator may experience these types of difficulties.
   180  
   181  ## Handling Reboots
   182  
   183  Provisioning sometimes involves restarts, usually when updating the operating
   184  system. Packer is able to tolerate restarts via the shell provisioner.
   185  
   186  Packer handles this by retrying to start scripts for a period of time before
   187  failing. This allows time for the machine to start up and be ready to run
   188  scripts. The amount of time the provisioner will wait is configured using
   189  `start_retry_timeout`, which defaults to a few minutes.
   190  
   191  Sometimes, when executing a command like `reboot`, the shell script will return
   192  and Packer will start executing the next one before SSH actually quits and the
   193  machine restarts. For this, put use "pause\_before" to make Packer wait before executing the next script:
   194  
   195  ``` json
   196  {
   197    "type": "shell",
   198    "script": "script.sh",
   199    "pause_before": "10s"
   200  }
   201  ```
   202  
   203  Some OS configurations don't properly kill all network connections on reboot,
   204  causing the provisioner to hang despite a reboot occurring. In this case, make
   205  sure you shut down the network interfaces on reboot or in your shell script. For
   206  example, on Gentoo:
   207  
   208  ``` text
   209  /etc/init.d/net.eth0 stop
   210  ```
   211  
   212  ## SSH Agent Forwarding
   213  
   214  Some provisioning requires connecting to remote SSH servers from within the
   215  packer instance. The below example is for pulling code from a private git
   216  repository utilizing openssh on the client. Make sure you are running
   217  `ssh-agent` and add your git repo ssh keys into it using `ssh-add /path/to/key`.
   218  When the packer instance needs access to the ssh keys the agent will forward the
   219  request back to your `ssh-agent`.
   220  
   221  Note: when provisioning via git you should add the git server keys into the
   222  `~/.ssh/known_hosts` file otherwise the git command could hang awaiting input.
   223  This can be done by copying the file in via the [file
   224  provisioner](/docs/provisioners/file.html) (more secure) or using `ssh-keyscan`
   225  to populate the file (less secure). An example of the latter accessing github
   226  would be:
   227  
   228  ``` json
   229  {
   230    "type": "shell",
   231    "inline": [
   232      "sudo apt-get install -y git",
   233      "ssh-keyscan github.com >> ~/.ssh/known_hosts",
   234      "git clone git@github.com:exampleorg/myprivaterepo.git"
   235    ]
   236  }
   237  ```
   238  
   239  ## Troubleshooting
   240  
   241  *My shell script doesn't work correctly on Ubuntu*
   242  
   243  -   On Ubuntu, the `/bin/sh` shell is
   244      [dash](https://en.wikipedia.org/wiki/Debian_Almquist_shell). If your script
   245      has [bash](https://en.wikipedia.org/wiki/Bash_(Unix_shell))-specific
   246      commands in it, then put `#!/bin/bash -e` at the top of your script.
   247      Differences between dash and bash can be found on the
   248      [DashAsBinSh](https://wiki.ubuntu.com/DashAsBinSh) Ubuntu wiki page.
   249  
   250  *My shell works when I login but fails with the shell provisioner*
   251  
   252  -   See the above tip. More than likely, your login shell is using `/bin/bash`
   253      while the provisioner is using `/bin/sh`.
   254  
   255  *My installs hang when using `apt-get` or `yum`*
   256  
   257  -   Make sure you add a `-y` to the command to prevent it from requiring user
   258      input before proceeding.
   259  
   260  *How do I tell what my shell script is doing?*
   261  
   262  -   Adding a `-x` flag to the shebang at the top of the script (`#!/bin/sh -x`)
   263      will echo the script statements as it is executing.
   264  
   265  *My builds don't always work the same*
   266  
   267  -   Some distributions start the SSH daemon before other core services which can
   268      create race conditions. Your first provisioner can tell the machine to wait
   269      until it completely boots.
   270  
   271  ```json
   272  {
   273    "type": "shell",
   274    "inline": [ "sleep 10" ]
   275  }
   276  ```
   277  
   278  ## Quoting Environment Variables
   279  
   280  Packer manages quoting for you, so you should't have to worry about it.
   281  Below is an example of packer template inputs and what you should expect to get
   282  out:
   283  
   284  ```json
   285    "provisioners": [
   286      {
   287        "type":  "shell",
   288        "environment_vars": ["FOO=foo",
   289                             "BAR=bar's",
   290                             "BAZ=baz=baz",
   291                             "QUX==qux",
   292                             "FOOBAR=foo bar",
   293                             "FOOBARBAZ='foo bar baz'",
   294                             "QUX2=\"qux\""],
   295        "inline": ["echo \"FOO is $FOO\"",
   296                   "echo \"BAR is $BAR\"",
   297                   "echo \"BAZ is $BAZ\"",
   298                   "echo \"QUX is $QUX\"",
   299                   "echo \"FOOBAR is $FOOBAR\"",
   300                   "echo \"FOOBARBAZ is $FOOBARBAZ\"",
   301                   "echo \"QUX2 is $QUX2\""]
   302      }
   303  ```
   304  
   305  Output:
   306  
   307  ```
   308      docker: FOO is foo
   309      docker: BAR is bar's
   310      docker: BAZ is baz=baz
   311      docker: QUX is =qux
   312      docker: FOOBAR is foo bar
   313      docker: FOOBARBAZ is 'foo bar baz'
   314      docker: QUX2 is "qux"
   315  ```