provisioner(converge): interpolate execute_command

This commit is contained in:
Brian Hicks 2016-12-27 16:48:11 -06:00
parent fe4b972d32
commit 3311d3a48d
No known key found for this signature in database
GPG Key ID: FF1F407C0D3C2430
2 changed files with 57 additions and 29 deletions

View File

@ -38,6 +38,7 @@ type Config struct {
Module string `mapstructure:"module"` Module string `mapstructure:"module"`
WorkingDirectory string `mapstructure:"working_directory"` WorkingDirectory string `mapstructure:"working_directory"`
Params map[string]string `mapstucture:"params"` Params map[string]string `mapstucture:"params"`
ExecuteCommand string `mapstructure:"execute_command"`
ctx interpolate.Context ctx interpolate.Context
} }
@ -71,6 +72,20 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
return err return err
} }
// require a single module
if p.config.Module == "" {
return errors.New("Converge requires a module to provision the system")
}
// set defaults
if p.config.WorkingDirectory == "" {
p.config.WorkingDirectory = "/tmp"
}
if p.config.ExecuteCommand == "" {
p.config.ExecuteCommand = "cd {{.WorkingDirectory}} && sudo converge apply --local --log-level=WARNING --paramsJSON '{{.ParamsJSON}}' {{.Module}}"
}
// validate version // validate version
if !versionRegex.Match([]byte(p.config.Version)) { if !versionRegex.Match([]byte(p.config.Version)) {
return fmt.Errorf("Invalid Converge version %q specified. Valid versions include only letters, numbers, dots, and dashes", p.config.Version) return fmt.Errorf("Invalid Converge version %q specified. Valid versions include only letters, numbers, dots, and dashes", p.config.Version)
@ -86,15 +101,6 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
} }
} }
// validate modules
if p.config.Module == "" {
return errors.New("Converge requires a module to provision the system")
}
if p.config.WorkingDirectory == "" {
p.config.WorkingDirectory = "/tmp"
}
return err return err
} }
@ -183,15 +189,22 @@ func (p *Provisioner) applyModules(ui packer.Ui, comm packer.Communicator) error
return fmt.Errorf("Could not marshal parameters as JSON: %s", err) return fmt.Errorf("Could not marshal parameters as JSON: %s", err)
} }
p.config.ctx.Data = struct {
ParamsJSON, WorkingDirectory, Module string
}{
ParamsJSON: string(params),
WorkingDirectory: p.config.WorkingDirectory,
Module: p.config.Module,
}
command, err := interpolate.Render(p.config.ExecuteCommand, &p.config.ctx)
if err != nil {
return fmt.Errorf("Could not interpolate execute command: %s", err)
}
// run Converge in the specified directory // run Converge in the specified directory
var runOut bytes.Buffer var runOut bytes.Buffer
cmd := &packer.RemoteCmd{ cmd := &packer.RemoteCmd{
Command: fmt.Sprintf( Command: command,
"cd %s && converge apply --local --log-level=WARNING --paramsJSON '%s' %s",
p.config.WorkingDirectory,
string(params),
p.config.Module,
),
Stdin: nil, Stdin: nil,
Stdout: &runOut, Stdout: &runOut,
Stderr: &runOut, Stderr: &runOut,

View File

@ -31,22 +31,37 @@ func TestProvisioner_Impl(t *testing.T) {
func TestProvisionerPrepare(t *testing.T) { func TestProvisionerPrepare(t *testing.T) {
t.Run("defaults", func(t *testing.T) { t.Run("defaults", func(t *testing.T) {
t.Run("working_directory", func(t *testing.T) {
var p Provisioner var p Provisioner
config := testConfig() config := testConfig()
// delete any keys that we're testing here to make sure they're actually
// being set by `Prepare`
delete(config, "working_directory") delete(config, "working_directory")
if err := p.Prepare(config); err != nil { if err := p.Prepare(config); err != nil {
t.Errorf("err: %s", err) t.Fatalf("err: %s", err)
} }
if p.config.WorkingDirectory != "/tmp" { if p.config.WorkingDirectory != "/tmp" {
t.Errorf("unexpected module directory: %s", p.config.WorkingDirectory) t.Fatalf("unexpected module directory: %s", p.config.WorkingDirectory)
} }
}) })
t.Run("execute_command", func(t *testing.T) {
var p Provisioner
config := testConfig()
delete(config, "execute_command")
if err := p.Prepare(config); err != nil {
t.Fatalf("err: %s", err)
}
if p.config.ExecuteCommand == "" {
t.Fatal("execute command unexpectedly blank")
}
})
})
t.Run("validate", func(t *testing.T) { t.Run("validate", func(t *testing.T) {
t.Run("bad version", func(t *testing.T) { t.Run("bad version", func(t *testing.T) {
var p Provisioner var p Provisioner