add new feature for telling shell-local whether to use linux pathing on windows; update docs with some examples.
This commit is contained in:
parent
e983a94a88
commit
51bcc7aa13
|
@ -4,6 +4,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
|
@ -44,6 +45,8 @@ type Config struct {
|
|||
// can be used to inject the environment_vars into the environment.
|
||||
ExecuteCommand []string `mapstructure:"execute_command"`
|
||||
|
||||
UseLinuxPathing bool `mapstructure:"use_linux_pathing"`
|
||||
|
||||
Ctx interpolate.Context
|
||||
}
|
||||
|
||||
|
@ -67,11 +70,6 @@ func Decode(config *Config, raws ...interface{}) error {
|
|||
func Validate(config *Config) error {
|
||||
var errs *packer.MultiError
|
||||
|
||||
// Do not treat these defaults as a source of truth; the shell-local
|
||||
// provisioner sets these defaults before Validate is called. Eventually
|
||||
// we will have to bring the provisioner and post-processor defaults in
|
||||
// line with one another, but for now the following may or may not be
|
||||
// applied depending on where Validate is being called from.
|
||||
if runtime.GOOS == "windows" {
|
||||
if len(config.ExecuteCommand) == 0 {
|
||||
config.ExecuteCommand = []string{
|
||||
|
@ -89,7 +87,8 @@ func Validate(config *Config) error {
|
|||
config.ExecuteCommand = []string{
|
||||
"/bin/sh",
|
||||
"-c",
|
||||
"{{.Vars}} {{.Script}}",
|
||||
"{{.Vars}}",
|
||||
"{{.Script}}",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -146,6 +145,15 @@ func Validate(config *Config) error {
|
|||
fmt.Errorf("Bad script '%s': %s", path, err))
|
||||
}
|
||||
}
|
||||
if config.UseLinuxPathing {
|
||||
for index, script := range config.Scripts {
|
||||
converted, err := convertToLinuxPath(script)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config.Scripts[index] = converted
|
||||
}
|
||||
}
|
||||
|
||||
// Do a check for bad environment variables, such as '=foo', 'foobar'
|
||||
for _, kv := range config.Vars {
|
||||
|
@ -162,3 +170,16 @@ func Validate(config *Config) error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
// C:/path/to/your/file becomes /mnt/c/path/to/your/file
|
||||
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 {
|
||||
return "", fmt.Errorf("Error converting %s to absolute path: %s", winPath, err.Error())
|
||||
}
|
||||
winAbsPath = strings.Replace(winAbsPath, "\\", "/", -1)
|
||||
splitPath := strings.SplitN(winAbsPath, ":/", 2)
|
||||
winBashPath := fmt.Sprintf("/mnt/%s/%s", strings.ToLower(splitPath[0]), splitPath[1])
|
||||
return winBashPath, nil
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
|
@ -144,8 +145,17 @@ func createFlattenedEnvVars(config *Config) (flattened string) {
|
|||
sort.Strings(keys)
|
||||
|
||||
// Re-assemble vars surrounding value with single quotes and flatten
|
||||
if runtime.GOOS == "windows" {
|
||||
log.Printf("MEGAN NEED TO IMPLEMENT")
|
||||
// createEnvVarsSourceFileWindows()
|
||||
}
|
||||
for _, key := range keys {
|
||||
flattened += fmt.Sprintf("%s='%s' ", key, envVars[key])
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// func createFlattenedEnvVarsWindows(
|
||||
// // The default shell, cmd, can set vars via dot sourcing
|
||||
// // set TESTXYZ=XYZ
|
||||
// )
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
package shell
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
sl "github.com/hashicorp/packer/common/shell-local"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
@ -19,44 +14,15 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
convertPath := false
|
||||
if len(p.config.ExecuteCommand) == 0 && runtime.GOOS == "windows" {
|
||||
convertPath = true
|
||||
p.config.ExecuteCommand = []string{
|
||||
"bash",
|
||||
"-c",
|
||||
"{{.Vars}} {{.Script}}",
|
||||
}
|
||||
}
|
||||
|
||||
err = sl.Validate(&p.config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if convertPath {
|
||||
for index, script := range p.config.Scripts {
|
||||
p.config.Scripts[index], err = convertToWindowsBashPath(script)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func convertToWindowsBashPath(winPath string) (string, error) {
|
||||
// get absolute path of script, and morph it into the bash path
|
||||
winAbsPath, err := filepath.Abs(winPath)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Error converting %s to absolute path: %s", winPath, err.Error())
|
||||
}
|
||||
winAbsPath = strings.Replace(winAbsPath, "\\", "/", -1)
|
||||
winBashPath := strings.Replace(winAbsPath, "C:/", "/mnt/c/", 1)
|
||||
return winBashPath, nil
|
||||
}
|
||||
|
||||
func (p *Provisioner) Provision(ui packer.Ui, _ packer.Communicator) error {
|
||||
_, retErr := sl.Run(ui, &p.config)
|
||||
if retErr != nil {
|
||||
|
|
|
@ -60,7 +60,7 @@ Optional parameters:
|
|||
as well, which are covered in the section below.
|
||||
|
||||
- `execute_command` (array of strings) - The command used to execute the script. By
|
||||
default this is `["sh", "-c", "chmod +x \"{{.Script}}\"; {{.Vars}} \"{{.Script}}\""]`
|
||||
default this is `["/bin/sh", "-c", "{{.Vars}}, "{{.Script}}"]`
|
||||
on unix and `["cmd", "/c", "{{.Vars}}", "{{.Script}}"]` on windows.
|
||||
This is treated as a [template engine](/docs/templates/engine.html).
|
||||
There are two available variables: `Script`, which is the path to the script
|
||||
|
@ -69,7 +69,9 @@ Optional parameters:
|
|||
array is the shell program you want to use (for example, "sh" or
|
||||
"/usr/local/bin/zsh" or even "powershell.exe" although anything other than
|
||||
a flavor of the shell command language is not explicitly supported and may
|
||||
be broken by assumptions made within Packer).
|
||||
be broken by assumptions made within Packer). It's worth noting that if you
|
||||
choose to try to use shell-local for Powershell or other Windows commands,
|
||||
the environment variables will not be set properly for your environment.
|
||||
|
||||
For backwards compatibility, `execute_command` will accept a string insetad
|
||||
of an array of strings. If a single string or an array of strings with only
|
||||
|
@ -89,13 +91,46 @@ Optional parameters:
|
|||
**Important:** If you customize this, be sure to include something like the
|
||||
`-e` flag, otherwise individual steps failing won't fail the provisioner.
|
||||
|
||||
## Execute Command Example
|
||||
- `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).
|
||||
|
||||
## 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
|
||||
|
||||
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 example below is a fully functional test config.
|
||||
|
||||
```
|
||||
{
|
||||
"builders": [
|
||||
{
|
||||
"type": "null",
|
||||
"communicator": "none"
|
||||
}
|
||||
],
|
||||
"provisioners": [
|
||||
{
|
||||
"type": "shell-local",
|
||||
"environment_vars": ["PROVISIONERTEST=ProvisionerTest1"],
|
||||
"execute_command": ["bash", "-c", "{{.Vars}} {{.Script}}"]
|
||||
"use_linux_pathing": true
|
||||
"scripts": ["./scripts/.sh"]
|
||||
},
|
||||
```
|
||||
|
||||
## Default Environmental Variables
|
||||
|
||||
In addition to being able to specify custom environmental variables using the
|
||||
|
|
Loading…
Reference in New Issue