provisioner/shell: Support setting the execute command

This commit is contained in:
Mitchell Hashimoto 2013-06-06 23:14:31 -07:00
parent e9b552ba18
commit 4a8278d49b
4 changed files with 28 additions and 10 deletions

View File

@ -3,6 +3,7 @@
package shell package shell
import ( import (
"bytes"
"fmt" "fmt"
"github.com/mitchellh/iochan" "github.com/mitchellh/iochan"
"github.com/mitchellh/mapstructure" "github.com/mitchellh/mapstructure"
@ -11,24 +12,32 @@ import (
"log" "log"
"os" "os"
"strings" "strings"
"text/template"
) )
const DefaultRemotePath = "/tmp/script.sh" const DefaultRemotePath = "/tmp/script.sh"
// TODO(mitchellh): config
type config struct { type config struct {
// The local path of the shell script to upload and execute. // The local path of the shell script to upload and execute.
Path string Path string
// The remote path where the local shell script will be uploaded to. // The remote path where the local shell script will be uploaded to.
// This should be set to a writable file that is in a pre-existing directory. // This should be set to a writable file that is in a pre-existing directory.
RemotePath string RemotePath string `mapstructure:"remote_path"`
// The command used to execute the script. The '{{ .Path }}' variable
// should be used to specify where the script goes.
ExecuteCommand string `mapstructure:"execute_command"`
} }
type Provisioner struct { type Provisioner struct {
config config config config
} }
type ExecuteCommandTemplate struct {
Path string
}
func (p *Provisioner) Prepare(raws ...interface{}) error { func (p *Provisioner) Prepare(raws ...interface{}) error {
for _, raw := range raws { for _, raw := range raws {
if err := mapstructure.Decode(raw, &p.config); err != nil { if err := mapstructure.Decode(raw, &p.config); err != nil {
@ -36,6 +45,10 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
} }
} }
if p.config.ExecuteCommand == "" {
p.config.ExecuteCommand = "chmod +x {{.Path}} && {{.Path}}"
}
if p.config.RemotePath == "" { if p.config.RemotePath == "" {
p.config.RemotePath = DefaultRemotePath p.config.RemotePath = DefaultRemotePath
} }
@ -60,12 +73,17 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) {
return return
} }
// Compile the command
var command bytes.Buffer
t := template.Must(template.New("command").Parse(p.config.ExecuteCommand))
t.Execute(&command, &ExecuteCommandTemplate{p.config.RemotePath})
// Setup the remote command // Setup the remote command
stdout_r, stdout_w := io.Pipe() stdout_r, stdout_w := io.Pipe()
stderr_r, stderr_w := io.Pipe() stderr_r, stderr_w := io.Pipe()
var cmd packer.RemoteCmd var cmd packer.RemoteCmd
cmd.Command = fmt.Sprintf("chmod +x %s && %s", p.config.RemotePath, p.config.RemotePath) cmd.Command = command.String()
cmd.Stdout = stdout_w cmd.Stdout = stdout_w
cmd.Stderr = stderr_w cmd.Stderr = stderr_w