From dd183f22d9c78524884de923eaf791e5ca3c7eed Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Fri, 9 Mar 2018 15:14:52 -0800 Subject: [PATCH] update docs and add warnings around WSL limitations --- common/shell-local/config.go | 12 ++- .../docs/post-processors/shell-local.html.md | 36 +++++-- .../docs/provisioners/shell-local.html.md | 97 +++++++++++++++++++ 3 files changed, 136 insertions(+), 9 deletions(-) diff --git a/common/shell-local/config.go b/common/shell-local/config.go index 80751aee7..64dfe25c1 100644 --- a/common/shell-local/config.go +++ b/common/shell-local/config.go @@ -147,12 +147,20 @@ func Validate(config *Config) error { } if config.UseLinuxPathing { for index, script := range config.Scripts { - converted, err := convertToLinuxPath(script) + converted, err := ConvertToLinuxPath(script) if err != nil { return err } config.Scripts[index] = converted } + // Interoperability issues with WSL makes creating and running tempfiles + // via golang's os package basically impossible. + if len(config.Inline) > 0 { + errs = packer.MultiErrorAppend(errs, + fmt.Errorf("Packer is unable to use the Command and Inline "+ + "features with the Windows Linux Subsystem. Please use "+ + "the Script or Scripts options instead")) + } } // Do a check for bad environment variables, such as '=foo', 'foobar' @@ -172,7 +180,7 @@ func Validate(config *Config) error { } // C:/path/to/your/file becomes /mnt/c/path/to/your/file -func convertToLinuxPath(winPath string) (string, error) { +func ConvertToLinuxPath(winPath string) (string, error) { // get absolute path of script, and morph it into the bash path winAbsPath, err := filepath.Abs(winPath) if err != nil { diff --git a/website/source/docs/post-processors/shell-local.html.md b/website/source/docs/post-processors/shell-local.html.md index e2bc324da..ab2f4bba3 100644 --- a/website/source/docs/post-processors/shell-local.html.md +++ b/website/source/docs/post-processors/shell-local.html.md @@ -96,7 +96,10 @@ Optional parameters: Linux feature enabled, and would like to invoke a bash script rather than invoking a Cmd script, you'll need to set this flag to true; it tells Packer to use the linux subsystem path for your script rather than the Windows path. - (e.g. /mnt/c/path/to/your/file instead of C:/path/to/your/file). + (e.g. /mnt/c/path/to/your/file instead of C:/path/to/your/file). Please see + the example below for more guidance on how to use this feature. If you are + not on a Windows host, or you do not intend to use the shell-local + post-processor to run a bash script, please ignore this option. ## Execute Command @@ -107,12 +110,22 @@ need to customize this if you use a non-POSIX shell, such as `tcsh` on FreeBSD. ### The Windows Linux Subsystem -If you have a bash script that you'd like to run on your Windows Linux -Subsystem as part of the shell-local post-processor, you must set -`execute_command` and `use_linux_pathing`. +The shell-local post-processor was designed with the idea of allowing you to run +commands in your local operating system's native shell. For Windows, we've +assumed in our defaults that this is Cmd. However, it is possible to run a +bash script as part of the Windows Linux Subsystem from the shell-local +post-processor, by modifying the `execute_command` and the `use_linux_pathing` +options in the post-processor config. The example below is a fully functional test config. +One limitation of this offering is that "inline" and "command" options are not +available to you; please limit yourself to using the "script" or "scripts" +options instead. + +Please note that the WSL is a beta feature, and this tool is not guaranteed to +work as you expect it to. + ``` { "builders": [ @@ -125,10 +138,19 @@ The example below is a fully functional test config. { "type": "shell-local", "environment_vars": ["PROVISIONERTEST=ProvisionerTest1"], - "execute_command": ["bash", "-c", "{{.Vars}} {{.Script}}"] - "use_linux_pathing": true - "scripts": ["./scripts/.sh"] + "execute_command": ["bash", "-c", "{{.Vars}} {{.Script}}"], + "use_linux_pathing": true, + "scripts": ["C:/Users/me/scripts/example_bash.sh"] }, + { + "type": "shell-local", + "environment_vars": ["PROVISIONERTEST=ProvisionerTest2"], + "execute_command": ["bash", "-c", "{{.Vars}} {{.Script}}"], + "use_linux_pathing": true, + "script": "C:/Users/me/scripts/example_bash.sh" + } + ] +} ``` ## Default Environmental Variables diff --git a/website/source/docs/provisioners/shell-local.html.md b/website/source/docs/provisioners/shell-local.html.md index bd66e74c7..f40c4e9f0 100644 --- a/website/source/docs/provisioners/shell-local.html.md +++ b/website/source/docs/provisioners/shell-local.html.md @@ -97,3 +97,100 @@ Optional parameters: you're not using `inline`, then this configuration has no effect. **Important:** If you customize this, be sure to include something like the `-e` flag, otherwise individual steps failing won't fail the provisioner. + +- `use_linux_pathing` (bool) - This is only relevant to windows hosts. If you + are running Packer in a Windows environment with the Windows Subsystem for + Linux feature enabled, and would like to invoke a bash script rather than + invoking a Cmd script, you'll need to set this flag to true; it tells Packer + to use the linux subsystem path for your script rather than the Windows path. + (e.g. /mnt/c/path/to/your/file instead of C:/path/to/your/file). Please see + the example below for more guidance on how to use this feature. If you are + not on a Windows host, or you do not intend to use the shell-local + provisioner to run a bash script, please ignore this option. + +## Execute Command + +To many new users, the `execute_command` is puzzling. However, it provides an +important function: customization of how the command is executed. The most +common use case for this is dealing with **sudo password prompts**. You may also +need to customize this if you use a non-POSIX shell, such as `tcsh` on FreeBSD. + +### The Windows Linux Subsystem + +The shell-local provisioner was designed with the idea of allowing you to run +commands in your local operating system's native shell. For Windows, we've +assumed in our defaults that this is Cmd. However, it is possible to run a +bash script as part of the Windows Linux Subsystem from the shell-local +provisioner, by modifying the `execute_command` and the `use_linux_pathing` +options in the provisioner config. + +The example below is a fully functional test config. + +One limitation of this offering is that "inline" and "command" options are not +available to you; please limit yourself to using the "script" or "scripts" +options instead. + +Please note that the WSL is a beta feature, and this tool is not guaranteed to +work as you expect it to. + +``` +{ + "builders": [ + { + "type": "null", + "communicator": "none" + } + ], + "provisioners": [ + { + "type": "shell-local", + "environment_vars": ["PROVISIONERTEST=ProvisionerTest1"], + "execute_command": ["bash", "-c", "{{.Vars}} {{.Script}}"], + "use_linux_pathing": true, + "scripts": ["C:/Users/me/scripts/example_bash.sh"] + }, + { + "type": "shell-local", + "environment_vars": ["PROVISIONERTEST=ProvisionerTest2"], + "execute_command": ["bash", "-c", "{{.Vars}} {{.Script}}"], + "use_linux_pathing": true, + "script": "C:/Users/me/scripts/example_bash.sh" + } + ] +} +``` + +## Default Environmental Variables + +In addition to being able to specify custom environmental variables using the +`environment_vars` configuration, the provisioner automatically defines certain +commonly useful environmental variables: + +- `PACKER_BUILD_NAME` is set to the name of the build that Packer is running. + This is most useful when Packer is making multiple builds and you want to + distinguish them slightly from a common provisioning script. + +- `PACKER_BUILDER_TYPE` is the type of the builder that was used to create the + machine that the script is running on. This is useful if you want to run + only certain parts of the script on systems built with certain builders. + +## Safely Writing A Script + +Whether you use the `inline` option, or pass it a direct `script` or `scripts`, +it is important to understand a few things about how the shell-local +provisioner works to run it safely and easily. This understanding will save +you much time in the process. + +### Once Per Builder + +The `shell-local` script(s) you pass are run once per builder. That means that +if you have an `amazon-ebs` builder and a `docker` builder, your script will be +run twice. If you have 3 builders, it will run 3 times, once for each builder. + +### Always Exit Intentionally + +If any provisioner fails, the `packer build` stops and all interim artifacts +are cleaned up. + +For a shell script, that means the script **must** exit with a zero code. You +*must* be extra careful to `exit 0` when necessary.