Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,29 @@ Stdout and stderr are also available in the debug log files. You can get this by
export TF_LOG=debug
```

### Interpreter
By default, the scripts will be executed by `cmd /C` on windows and `/bin/sh -c` on linux. You can overwrite this setting using `interpreter`:

resource "shell_script" "test" {
lifecycle_commands {
create = file("create.sh")
read = file("read.sh")
update = file("update.sh")
delete = file("delete.sh")
}

interpreter = {
shell = "/bin/bash"
flag = "-c"
}
}

* `shell` (optional) contains the path to the shell binary. If empty or non present, it will be set to `cmd` on windows and `/bin/sh` otherwise.
* `flag` (optional) contains the options passed to the shell (this example will execute `/bin/bash -c create.sh`). Can be empty.

## Python Support
There is now an example for how to use the shell provider to invoke python files. Please check in the test/python-example folder for more information on this. Essentially it is an adapter around the shell resource that invokes methods on an interface that you implement.

## Python and Golang Support
There is now an example for how to use the shell provider to invoke python and golang files. Please check in the `examples/python-adapter` and `examples/golang-adapter` folder for more information on this. Essentially it is an adapter around the `shell_resource` that invokes methods on an interface that you implement.

Expand Down
19 changes: 19 additions & 0 deletions examples/test/test.tf
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,22 @@ resource "shell_script" "test6" {
abc = 123
}
}

//test interpreter
resource "shell_script" "test7" {
lifecycle_commands {
create = <<EOF
out='{"commit_id": "b8f2b8b"}'
touch test7.json
echo $out >> test7.json
cat test7.json
EOF
read = "cat test7.json"
delete = "rm -rf test7.json"
}

interpreter = {
shell = "/bin/bash" # will probably crash on windows!
flag = "-c"
}
}
10 changes: 9 additions & 1 deletion shell/data_source_shell_script.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ func dataSourceShellScript() *schema.Resource {
Computed: true,
Elem: schema.TypeString,
},
"interpreter": {
Type: schema.TypeMap,
Optional: true,
Elem: schema.TypeString,
},
},
}
}
Expand All @@ -57,11 +62,14 @@ func dataSourceShellScriptRead(d *schema.ResourceData, meta interface{}) error {
command := value.(string)
vars := d.Get("environment").(map[string]interface{})
environment := readEnvironmentVariables(vars)

inter := d.Get("interpreter").(map[string]interface{})

workingDirectory := d.Get("working_directory").(string)
output := make(map[string]string)

state := NewState(environment, output)
newState, err := runCommand(command, state, environment, workingDirectory)
newState, err := runCommand(command, state, environment, workingDirectory, inter)
if err != nil {
return err
}
Expand Down
25 changes: 20 additions & 5 deletions shell/resource_shell_script.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ func resourceShellScript() *schema.Resource {
Optional: true,
Default: false,
},
"interpreter": {
Type: schema.TypeMap,
Optional: true,
Elem: schema.TypeString,
},
},
}
}
Expand Down Expand Up @@ -101,12 +106,15 @@ func create(d *schema.ResourceData, meta interface{}, stack []string) error {
command := c["create"].(string)
vars := d.Get("environment").(map[string]interface{})
environment := readEnvironmentVariables(vars)

inter := d.Get("interpreter").(map[string]interface{})

workingDirectory := d.Get("working_directory").(string)
d.MarkNewResource()

output := make(map[string]string)
state := NewState(environment, output)
newState, err := runCommand(command, state, environment, workingDirectory)
newState, err := runCommand(command, state, environment, workingDirectory, inter)
if err != nil {
return err
}
Expand Down Expand Up @@ -141,6 +149,9 @@ func read(d *schema.ResourceData, meta interface{}, stack []string) error {

vars := d.Get("environment").(map[string]interface{})
environment := readEnvironmentVariables(vars)

inter := d.Get("interpreter").(map[string]interface{})

workingDirectory := d.Get("working_directory").(string)
o := d.Get("output").(map[string]interface{})
output := make(map[string]string)
Expand All @@ -149,7 +160,7 @@ func read(d *schema.ResourceData, meta interface{}, stack []string) error {
}

state := NewState(environment, output)
newState, err := runCommand(command, state, environment, workingDirectory)
newState, err := runCommand(command, state, environment, workingDirectory, inter)
if err != nil {
return err
}
Expand All @@ -159,7 +170,6 @@ func read(d *schema.ResourceData, meta interface{}, stack []string) error {
d.SetId("")
return nil
}
log.Printf("[DEBUG] output:|%v|", output)
log.Printf("[DEBUG] new output:|%v|", newState.Output)
isStateEqual := reflect.DeepEqual(output, newState.Output)
isNewResource := d.IsNewResource()
Expand Down Expand Up @@ -201,6 +211,8 @@ func update(d *schema.ResourceData, meta interface{}, stack []string) error {
vars := d.Get("environment").(map[string]interface{})
environment := readEnvironmentVariables(vars)

inter := d.Get("interpreter").(map[string]interface{})

workingDirectory := d.Get("working_directory").(string)
o := d.Get("output").(map[string]interface{})
output := make(map[string]string)
Expand All @@ -209,7 +221,7 @@ func update(d *schema.ResourceData, meta interface{}, stack []string) error {
}

state := NewState(oldEnvironment, output)
newState, err := runCommand(command, state, environment, workingDirectory)
newState, err := runCommand(command, state, environment, workingDirectory, inter)
if err != nil {
return err
}
Expand All @@ -234,6 +246,9 @@ func delete(d *schema.ResourceData, meta interface{}, stack []string) error {
command := c["delete"].(string)
vars := d.Get("environment").(map[string]interface{})
environment := readEnvironmentVariables(vars)

inter := d.Get("interpreter").(map[string]interface{})

workingDirectory := d.Get("working_directory").(string)
o := d.Get("output").(map[string]interface{})
output := make(map[string]string)
Expand All @@ -242,7 +257,7 @@ func delete(d *schema.ResourceData, meta interface{}, stack []string) error {
}

state := NewState(environment, output)
runCommand(command, state, environment, workingDirectory)
runCommand(command, state, environment, workingDirectory, inter)

d.SetId("")
return nil
Expand Down
23 changes: 17 additions & 6 deletions shell/utility.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,29 @@ func printStackTrace(stack []string) {
log.Printf("-------------------------")
}

func runCommand(command string, state *State, environment []string, workingDirectory string) (*State, error) {
func runCommand(command string, state *State, environment []string, workingDirectory string, interpreter map[string]interface{}) (*State, error) {
shellMutexKV.Lock(shellScriptMutexKey)
defer shellMutexKV.Unlock(shellScriptMutexKey)

// Execute the command using a shell
var shell, flag string
if runtime.GOOS == "windows" {
shell = "cmd"
flag = "/C"
if value, ok := interpreter["shell"]; ok && value != "" {
shell = value.(string)
} else {
shell = "/bin/sh"
flag = "-c"
if runtime.GOOS == "windows" {
shell = "cmd"
} else {
shell = "/bin/sh"
}
}
if value, ok := interpreter["flag"]; ok {
flag = value.(string)
} else {
if runtime.GOOS == "windows" {
flag = "/C"
} else {
flag = "-c"
}
}

// Setup the command
Expand Down