From 4a8278d49b8c2ec77ce9af6abcc315ae302fd5c5 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 6 Jun 2013 23:14:31 -0700 Subject: [PATCH] provisioner/shell: Support setting the execute command --- packer/provisioner_test.go | 4 ++-- packer/rpc/provisioner.go | 2 +- packer/rpc/provisioner_test.go | 8 ++++---- provisioner/shell/provisioner.go | 24 +++++++++++++++++++++--- 4 files changed, 28 insertions(+), 10 deletions(-) diff --git a/packer/provisioner_test.go b/packer/provisioner_test.go index 49ab76dea..5eba77743 100644 --- a/packer/provisioner_test.go +++ b/packer/provisioner_test.go @@ -3,9 +3,9 @@ package packer import "testing" type TestProvisioner struct { - prepCalled bool + prepCalled bool prepConfigs []interface{} - provCalled bool + provCalled bool } func (t *TestProvisioner) Prepare(configs ...interface{}) error { diff --git a/packer/rpc/provisioner.go b/packer/rpc/provisioner.go index f2da4772d..53fc81776 100644 --- a/packer/rpc/provisioner.go +++ b/packer/rpc/provisioner.go @@ -18,7 +18,7 @@ type ProvisionerServer struct { } type ProvisionerPrepareArgs struct { - Configs []interface{} + Configs []interface{} } type ProvisionerProvisionArgs struct { diff --git a/packer/rpc/provisioner_test.go b/packer/rpc/provisioner_test.go index 293027388..bf027be99 100644 --- a/packer/rpc/provisioner_test.go +++ b/packer/rpc/provisioner_test.go @@ -8,11 +8,11 @@ import ( ) type testProvisioner struct { - prepareCalled bool + prepareCalled bool prepareConfigs []interface{} - provCalled bool - provComm packer.Communicator - provUi packer.Ui + provCalled bool + provComm packer.Communicator + provUi packer.Ui } func (p *testProvisioner) Prepare(configs ...interface{}) error { diff --git a/provisioner/shell/provisioner.go b/provisioner/shell/provisioner.go index 3f06ef0e1..f66128bf8 100644 --- a/provisioner/shell/provisioner.go +++ b/provisioner/shell/provisioner.go @@ -3,6 +3,7 @@ package shell import ( + "bytes" "fmt" "github.com/mitchellh/iochan" "github.com/mitchellh/mapstructure" @@ -11,24 +12,32 @@ import ( "log" "os" "strings" + "text/template" ) const DefaultRemotePath = "/tmp/script.sh" -// TODO(mitchellh): config type config struct { // The local path of the shell script to upload and execute. Path string // 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. - 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 { config config } +type ExecuteCommandTemplate struct { + Path string +} + func (p *Provisioner) Prepare(raws ...interface{}) error { for _, raw := range raws { 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 == "" { p.config.RemotePath = DefaultRemotePath } @@ -60,12 +73,17 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) { 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 stdout_r, stdout_w := io.Pipe() stderr_r, stderr_w := io.Pipe() 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.Stderr = stderr_w