provisioner/local-exec: allow user to specify interpreter
This commit is contained in:
parent
1dc3611fbd
commit
5d5f8224d2
|
@ -28,6 +28,12 @@ func Provisioner() terraform.ResourceProvisioner {
|
|||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"interpreter": &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
Optional: true,
|
||||
},
|
||||
},
|
||||
|
||||
ApplyFunc: applyFn,
|
||||
|
@ -39,19 +45,29 @@ func applyFn(ctx context.Context) error {
|
|||
o := ctx.Value(schema.ProvOutputKey).(terraform.UIOutput)
|
||||
|
||||
command := data.Get("command").(string)
|
||||
|
||||
if command == "" {
|
||||
return fmt.Errorf("local-exec provisioner command must be a non-empty string")
|
||||
}
|
||||
|
||||
// Execute the command using a shell
|
||||
var shell, flag string
|
||||
if runtime.GOOS == "windows" {
|
||||
shell = "cmd"
|
||||
flag = "/C"
|
||||
interpreter := data.Get("interpreter").([]interface{})
|
||||
|
||||
var cmdargs []string
|
||||
if len(interpreter) > 0 {
|
||||
for _, i := range interpreter {
|
||||
if arg, ok := i.(string); ok {
|
||||
cmdargs = append(cmdargs, arg)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
shell = "/bin/sh"
|
||||
flag = "-c"
|
||||
if runtime.GOOS == "windows" {
|
||||
cmdargs = []string{"cmd", "/C"}
|
||||
} else {
|
||||
cmdargs = []string{"/bin/sh", "-c"}
|
||||
}
|
||||
}
|
||||
cmdargs = append(cmdargs, command)
|
||||
|
||||
// Setup the reader that will read the output from the command.
|
||||
// We use an os.Pipe so that the *os.File can be passed directly to the
|
||||
|
@ -63,7 +79,7 @@ func applyFn(ctx context.Context) error {
|
|||
}
|
||||
|
||||
// Setup the command
|
||||
cmd := exec.CommandContext(ctx, shell, flag, command)
|
||||
cmd := exec.CommandContext(ctx, cmdargs[0], cmdargs[1:]...)
|
||||
cmd.Stderr = pw
|
||||
cmd.Stdout = pw
|
||||
|
||||
|
@ -77,9 +93,7 @@ func applyFn(ctx context.Context) error {
|
|||
go copyOutput(o, tee, copyDoneCh)
|
||||
|
||||
// Output what we're about to run
|
||||
o.Output(fmt.Sprintf(
|
||||
"Executing: %s %s \"%s\"",
|
||||
shell, flag, command))
|
||||
o.Output(fmt.Sprintf("Executing: %q", cmdargs))
|
||||
|
||||
// Start the command
|
||||
err = cmd.Start()
|
||||
|
|
|
@ -125,3 +125,23 @@ func testConfig(t *testing.T, c map[string]interface{}) *terraform.ResourceConfi
|
|||
|
||||
return terraform.NewResourceConfig(r)
|
||||
}
|
||||
|
||||
func TestResourceProvider_ApplyCustomInterpreter(t *testing.T) {
|
||||
c := testConfig(t, map[string]interface{}{
|
||||
"interpreter": []interface{}{"echo", "is"},
|
||||
"command": "not really an interpreter",
|
||||
})
|
||||
|
||||
output := new(terraform.MockUIOutput)
|
||||
p := Provisioner()
|
||||
|
||||
if err := p.Apply(output, nil, c); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
got := strings.TrimSpace(output.OutputMessage)
|
||||
want := "is not really an interpreter"
|
||||
if got != want {
|
||||
t.Errorf("wrong output\ngot: %s\nwant: %s", got, want)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,3 +38,31 @@ The following arguments are supported:
|
|||
as a relative path to the current working directory or as an absolute path.
|
||||
It is evaluated in a shell, and can use environment variables or Terraform
|
||||
variables.
|
||||
|
||||
* `interpreter` - (Optional) If provided, this is a list of interpreter
|
||||
arguments used to execute the command. The first argument is the
|
||||
interpreter itself. It can be provided as a relative path to the current
|
||||
working directory or as an absolute path. The remaining arguments are
|
||||
appended prior to the command. This allows building command lines of the
|
||||
form "/bin/bash", "-c", "echo foo". If `interpreter` is unspecified,
|
||||
sensible defaults will be chosen based on the system OS.
|
||||
|
||||
### Interpreter Examples
|
||||
|
||||
```hcl
|
||||
resource "null_resource" "example1" {
|
||||
provisioner "local-exec" {
|
||||
command = "open WFH, '>completed.txt' and print WFH scalar localtime"
|
||||
interpreter = ["perl", "-e"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```hcl
|
||||
resource "null_resource" "example2" {
|
||||
provisioner "local-exec" {
|
||||
command = "Get-Date > completed.txt"
|
||||
interpreter = ["PowerShell", "-Command"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
Loading…
Reference in New Issue