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"`
WorkingDirectory string `mapstructure:"working_directory"`
Params map[string]string `mapstucture:"params"`
ExecuteCommand string `mapstructure:"execute_command"`
ctx interpolate.Context
}
@ -71,6 +72,20 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
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
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)
@ -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
}
@ -183,18 +189,25 @@ func (p *Provisioner) applyModules(ui packer.Ui, comm packer.Communicator) error
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
var runOut bytes.Buffer
cmd := &packer.RemoteCmd{
Command: fmt.Sprintf(
"cd %s && converge apply --local --log-level=WARNING --paramsJSON '%s' %s",
p.config.WorkingDirectory,
string(params),
p.config.Module,
),
Stdin: nil,
Stdout: &runOut,
Stderr: &runOut,
Command: command,
Stdin: nil,
Stdout: &runOut,
Stderr: &runOut,
}
if err := comm.Start(cmd); err != nil {
return fmt.Errorf("Error applying %q: %s", p.config.Module, err)

View File

@ -31,20 +31,35 @@ func TestProvisioner_Impl(t *testing.T) {
func TestProvisionerPrepare(t *testing.T) {
t.Run("defaults", func(t *testing.T) {
var p Provisioner
config := testConfig()
t.Run("working_directory", func(t *testing.T) {
var p Provisioner
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 {
t.Errorf("err: %s", err)
}
if err := p.Prepare(config); err != nil {
t.Fatalf("err: %s", err)
}
if p.config.WorkingDirectory != "/tmp" {
t.Errorf("unexpected module directory: %s", p.config.WorkingDirectory)
}
if p.config.WorkingDirectory != "/tmp" {
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) {