add environments_path and chef_environment support to chef provisioner

This commit is contained in:
Chris 2013-10-01 11:20:36 -04:00
parent 5c41eccfd5
commit bc8e5d2c41
2 changed files with 86 additions and 16 deletions

View File

@ -22,6 +22,8 @@ type Config struct {
CookbookPaths []string `mapstructure:"cookbook_paths"` CookbookPaths []string `mapstructure:"cookbook_paths"`
RolesPath string `mapstructure:"roles_path"` RolesPath string `mapstructure:"roles_path"`
DataBagsPath string `mapstructure:"data_bags_path"` DataBagsPath string `mapstructure:"data_bags_path"`
EnvironmentsPath string `mapstructure:"environments_path"`
ChefEnvironment string `mapstructure:"chef_environment"`
ExecuteCommand string `mapstructure:"execute_command"` ExecuteCommand string `mapstructure:"execute_command"`
InstallCommand string `mapstructure:"install_command"` InstallCommand string `mapstructure:"install_command"`
RemoteCookbookPaths []string `mapstructure:"remote_cookbook_paths"` RemoteCookbookPaths []string `mapstructure:"remote_cookbook_paths"`
@ -39,15 +41,19 @@ type Provisioner struct {
} }
type ConfigTemplate struct { type ConfigTemplate struct {
CookbookPaths string CookbookPaths string
DataBagsPath string DataBagsPath string
RolesPath string RolesPath string
EnvironmentsPath string
ChefEnvironment string
// Templates don't support boolean statements until Go 1.2. In the // Templates don't support boolean statements until Go 1.2. In the
// mean time, we do this. // mean time, we do this.
// TODO(mitchellh): Remove when Go 1.2 is released // TODO(mitchellh): Remove when Go 1.2 is released
HasDataBagsPath bool HasDataBagsPath bool
HasRolesPath bool HasRolesPath bool
HasEnvironmentsPath bool
HasChefEnvironment bool
} }
type ExecuteTemplate struct { type ExecuteTemplate struct {
@ -92,10 +98,12 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
errs := common.CheckUnusedConfig(md) errs := common.CheckUnusedConfig(md)
templates := map[string]*string{ templates := map[string]*string{
"config_template": &p.config.ConfigTemplate, "config_template": &p.config.ConfigTemplate,
"data_bags_path": &p.config.DataBagsPath, "data_bags_path": &p.config.DataBagsPath,
"roles_path": &p.config.RolesPath, "roles_path": &p.config.RolesPath,
"staging_dir": &p.config.StagingDir, "staging_dir": &p.config.StagingDir,
"environments_path": &p.config.EnvironmentsPath,
"chef_environment": &p.config.ChefEnvironment,
} }
for n, ptr := range templates { for n, ptr := range templates {
@ -174,6 +182,15 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
} }
} }
if p.config.EnvironmentsPath != "" {
pFileInfo, err := os.Stat(p.config.EnvironmentsPath)
if err != nil || !pFileInfo.IsDir() {
errs = packer.MultiErrorAppend(
errs, fmt.Errorf("Bad environments path '%s': %s", p.config.EnvironmentsPath, err))
}
}
// Process the user variables within the JSON and set the JSON. // Process the user variables within the JSON and set the JSON.
// Do this early so that we can validate and show errors. // Do this early so that we can validate and show errors.
p.config.Json, err = p.processJsonUserVars() p.config.Json, err = p.processJsonUserVars()
@ -226,7 +243,15 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
} }
} }
configPath, err := p.createConfig(ui, comm, cookbookPaths, rolesPath, dataBagsPath) environmentsPath := ""
if p.config.EnvironmentsPath != "" {
environmentsPath = fmt.Sprintf("%s/environments", p.config.StagingDir)
if err := p.uploadDirectory(ui, comm, environmentsPath, p.config.EnvironmentsPath); err != nil {
return fmt.Errorf("Error uploading environments: %s", err)
}
}
configPath, err := p.createConfig(ui, comm, cookbookPaths, rolesPath, dataBagsPath, environmentsPath, p.config.ChefEnvironment)
if err != nil { if err != nil {
return fmt.Errorf("Error creating Chef config file: %s", err) return fmt.Errorf("Error creating Chef config file: %s", err)
} }
@ -263,7 +288,7 @@ func (p *Provisioner) uploadDirectory(ui packer.Ui, comm packer.Communicator, ds
return comm.UploadDir(dst, src, nil) return comm.UploadDir(dst, src, nil)
} }
func (p *Provisioner) createConfig(ui packer.Ui, comm packer.Communicator, localCookbooks []string, rolesPath string, dataBagsPath string) (string, error) { func (p *Provisioner) createConfig(ui packer.Ui, comm packer.Communicator, localCookbooks []string, rolesPath string, dataBagsPath string, environmentsPath string, chefEnvironment string) (string, error) {
ui.Message("Creating configuration file 'solo.rb'") ui.Message("Creating configuration file 'solo.rb'")
cookbook_paths := make([]string, len(p.config.RemoteCookbookPaths)+len(localCookbooks)) cookbook_paths := make([]string, len(p.config.RemoteCookbookPaths)+len(localCookbooks))
@ -294,11 +319,14 @@ func (p *Provisioner) createConfig(ui packer.Ui, comm packer.Communicator, local
} }
configString, err := p.config.tpl.Process(tpl, &ConfigTemplate{ configString, err := p.config.tpl.Process(tpl, &ConfigTemplate{
CookbookPaths: strings.Join(cookbook_paths, ","), CookbookPaths: strings.Join(cookbook_paths, ","),
RolesPath: rolesPath, RolesPath: rolesPath,
DataBagsPath: dataBagsPath, DataBagsPath: dataBagsPath,
HasRolesPath: rolesPath != "", EnvironmentsPath: environmentsPath,
HasDataBagsPath: dataBagsPath != "", HasRolesPath: rolesPath != "",
HasDataBagsPath: dataBagsPath != "",
HasEnvironmentsPath: environmentsPath != "",
ChefEnvironment: chefEnvironment,
}) })
if err != nil { if err != nil {
return "", err return "", err
@ -456,4 +484,8 @@ role_path "{{.RolesPath}}"
{{if .HasDataBagsPath}} {{if .HasDataBagsPath}}
data_bag_path "{{.DataBagsPath}}" data_bag_path "{{.DataBagsPath}}"
{{end}} {{end}}
{{if .HasEnvironmentsPath}}
environments_path "{{.EnvironmentsPath}}"
chef_environment "{{.ChefEnvironment}}"
{{end}}
` `

View File

@ -161,6 +161,44 @@ func TestProvisionerPrepare_rolesPath(t *testing.T) {
} }
} }
func TestProvisionerPrepare_environmentsPath(t *testing.T) {
var p Provisioner
environmentsPath, err := ioutil.TempDir("", "environments")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.Remove(environmentsPath)
config := testConfig()
config["environments_path"] = environmentsPath
err = p.Prepare(config)
if err != nil {
t.Fatalf("err: %s", err)
}
if p.config.EnvironmentsPath != environmentsPath {
t.Fatalf("unexpected: %#v", p.config.EnvironmentsPath)
}
}
func TestProvisionerPrepare_chefEnvironment(t *testing.T) {
var p Provisioner
config := testConfig()
config["chef_environment"] = "some-env"
err := p.Prepare(config)
if err != nil {
t.Fatalf("err: %s", err)
}
if p.config.ChefEnvironment != "some-env" {
t.Fatalf("unexpected: %#v", p.config.ChefEnvironment)
}
}
func TestProvisionerPrepare_json(t *testing.T) { func TestProvisionerPrepare_json(t *testing.T) {
config := testConfig() config := testConfig()
config["json"] = map[string]interface{}{ config["json"] = map[string]interface{}{