provisioner/remote-exec: Collect scripts to upload

This commit is contained in:
Armon Dadgar 2014-07-14 14:28:37 -07:00
parent cd3170b906
commit f215d31df4
3 changed files with 166 additions and 0 deletions

View File

@ -1,7 +1,11 @@
package remoteexec
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"os"
"strings"
"github.com/hashicorp/terraform/terraform"
@ -54,6 +58,13 @@ func (p *ResourceProvisioner) Apply(s *terraform.ResourceState,
return s, err
}
// Collect the scripts
_, err = p.collectScripts(c)
if err != nil {
return s, err
}
// For-each script, copy + exec
panic("not implemented")
return s, nil
}
@ -147,3 +158,64 @@ func (p *ResourceProvisioner) generateScript(c *terraform.ResourceConfig) (strin
lines = append(lines, "")
return strings.Join(lines, "\n"), nil
}
// collectScripts is used to collect all the scripts we need
// to execute in preperation for copying them.
func (p *ResourceProvisioner) collectScripts(c *terraform.ResourceConfig) ([]io.ReadCloser, error) {
// Check if inline
_, ok := c.Config["inline"]
if ok {
script, err := p.generateScript(c)
if err != nil {
return nil, err
}
rc := ioutil.NopCloser(bytes.NewReader([]byte(script)))
return []io.ReadCloser{rc}, nil
}
// Collect scripts
var scripts []string
s, ok := c.Config["script"]
if ok {
sStr, ok := s.(string)
if !ok {
return nil, fmt.Errorf("Unsupported 'script' type! Must be a string.")
}
scripts = append(scripts, sStr)
}
sl, ok := c.Config["scripts"]
if ok {
switch slt := sl.(type) {
case []string:
scripts = append(scripts, slt...)
case []interface{}:
for _, l := range slt {
lStr, ok := l.(string)
if ok {
scripts = append(scripts, lStr)
} else {
return nil, fmt.Errorf("Unsupported 'scripts' type! Must be list of strings.")
}
}
default:
return nil, fmt.Errorf("Unsupported 'scripts' type! Must be list of strings.")
}
}
// Open all the scripts
var fhs []io.ReadCloser
for _, s := range scripts {
fh, err := os.Open(s)
if err != nil {
for _, fh := range fhs {
fh.Close()
}
return nil, fmt.Errorf("Failed to open script '%s': %v", s, err)
}
fhs = append(fhs, fh)
}
// Done, return the file handles
return fhs, nil
}

View File

@ -1,6 +1,8 @@
package remoteexec
import (
"bytes"
"io"
"testing"
"github.com/hashicorp/terraform/config"
@ -126,6 +128,94 @@ wget http://foobar
exit 0
`
func TestResourceProvider_CollectScripts_inline(t *testing.T) {
p := new(ResourceProvisioner)
conf := testConfig(t, map[string]interface{}{
"inline": []string{
"cd /tmp",
"wget http://foobar",
"exit 0",
},
})
scripts, err := p.collectScripts(conf)
if err != nil {
t.Fatalf("err: %v", err)
}
if len(scripts) != 1 {
t.Fatalf("bad: %v", scripts)
}
var out bytes.Buffer
_, err = io.Copy(&out, scripts[0])
if err != nil {
t.Fatalf("err: %v", err)
}
if string(out.Bytes()) != expectedScriptOut {
t.Fatalf("bad: %v", out.Bytes())
}
}
func TestResourceProvider_CollectScripts_script(t *testing.T) {
p := new(ResourceProvisioner)
conf := testConfig(t, map[string]interface{}{
"script": "test-fixtures/script1.sh",
})
scripts, err := p.collectScripts(conf)
if err != nil {
t.Fatalf("err: %v", err)
}
if len(scripts) != 1 {
t.Fatalf("bad: %v", scripts)
}
var out bytes.Buffer
_, err = io.Copy(&out, scripts[0])
if err != nil {
t.Fatalf("err: %v", err)
}
if string(out.Bytes()) != expectedScriptOut {
t.Fatalf("bad: %v", out.Bytes())
}
}
func TestResourceProvider_CollectScripts_scripts(t *testing.T) {
p := new(ResourceProvisioner)
conf := testConfig(t, map[string]interface{}{
"scripts": []interface{}{
"test-fixtures/script1.sh",
"test-fixtures/script1.sh",
"test-fixtures/script1.sh",
},
})
scripts, err := p.collectScripts(conf)
if err != nil {
t.Fatalf("err: %v", err)
}
if len(scripts) != 3 {
t.Fatalf("bad: %v", scripts)
}
for idx := range scripts {
var out bytes.Buffer
_, err = io.Copy(&out, scripts[idx])
if err != nil {
t.Fatalf("err: %v", err)
}
if string(out.Bytes()) != expectedScriptOut {
t.Fatalf("bad: %v", out.Bytes())
}
}
}
func testConfig(
t *testing.T,
c map[string]interface{}) *terraform.ResourceConfig {

View File

@ -0,0 +1,4 @@
#!/bin/sh
cd /tmp
wget http://foobar
exit 0