provisioners/puppet-masterless: support hiera configs

This commit is contained in:
Mitchell Hashimoto 2013-09-09 13:24:17 -07:00
parent 41b70aae99
commit fd0df9ff58
3 changed files with 88 additions and 9 deletions

View File

@ -22,6 +22,9 @@ type Config struct {
// Additional facts to set when executing Puppet // Additional facts to set when executing Puppet
Facter map[string]string Facter map[string]string
// Path to a hiera configuration file to upload and use.
HieraConfigPath string `mapstructure:"hiera_config_path"`
// An array of local paths of modules to upload. // An array of local paths of modules to upload.
ModulePaths []string `mapstructure:"module_paths"` ModulePaths []string `mapstructure:"module_paths"`
@ -41,10 +44,12 @@ type Provisioner struct {
} }
type ExecuteTemplate struct { type ExecuteTemplate struct {
FacterVars string FacterVars string
ModulePath string HasHieraConfigPath bool
ManifestFile string HieraConfigPath string
Sudo bool ModulePath string
ManifestFile string
Sudo bool
} }
func (p *Provisioner) Prepare(raws ...interface{}) error { func (p *Provisioner) Prepare(raws ...interface{}) error {
@ -64,7 +69,10 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
// Set some defaults // Set some defaults
if p.config.ExecuteCommand == "" { if p.config.ExecuteCommand == "" {
p.config.ExecuteCommand = "{{.FacterVars}}{{if .Sudo}} sudo -E {{end}}puppet apply --verbose --modulepath='{{.ModulePath}}' {{.ManifestFile}}" p.config.ExecuteCommand = "{{.FacterVars}}{{if .Sudo}} sudo -E {{end}}" +
"puppet apply --verbose --modulepath='{{.ModulePath}}' " +
"{{if .HasHieraConfigPath}}--hiera_config='{{.HieraConfigPath}}' {{end}}" +
"{{.ManifestFile}}"
} }
if p.config.StagingDir == "" { if p.config.StagingDir == "" {
@ -133,6 +141,17 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
p.config.Facter = newFacts p.config.Facter = newFacts
// Validation // Validation
if p.config.HieraConfigPath != "" {
info, err := os.Stat(p.config.ManifestFile)
if err != nil {
errs = packer.MultiErrorAppend(errs,
fmt.Errorf("hiera_config_path is invalid: %s", err))
} else if info.IsDir() {
errs = packer.MultiErrorAppend(errs,
fmt.Errorf("hiera_config_path must point to a file"))
}
}
if p.config.ManifestFile == "" { if p.config.ManifestFile == "" {
errs = packer.MultiErrorAppend(errs, errs = packer.MultiErrorAppend(errs,
fmt.Errorf("A manifest_file must be specified.")) fmt.Errorf("A manifest_file must be specified."))
@ -171,6 +190,16 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
return fmt.Errorf("Error creating staging directory: %s", err) return fmt.Errorf("Error creating staging directory: %s", err)
} }
// Upload hiera config if set
remoteHieraConfigPath := ""
if p.config.HieraConfigPath != "" {
var err error
remoteHieraConfigPath, err = p.uploadHieraConfig(ui, comm)
if err != nil {
return fmt.Errorf("Error uploading hiera config: %s", err)
}
}
// Upload all modules // Upload all modules
modulePaths := make([]string, 0, len(p.config.ModulePaths)) modulePaths := make([]string, 0, len(p.config.ModulePaths))
for i, path := range p.config.ModulePaths { for i, path := range p.config.ModulePaths {
@ -198,10 +227,12 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
// Execute Puppet // Execute Puppet
command, err := p.config.tpl.Process(p.config.ExecuteCommand, &ExecuteTemplate{ command, err := p.config.tpl.Process(p.config.ExecuteCommand, &ExecuteTemplate{
FacterVars: strings.Join(facterVars, " "), FacterVars: strings.Join(facterVars, " "),
ManifestFile: remoteManifestFile, HasHieraConfigPath: remoteHieraConfigPath != "",
ModulePath: strings.Join(modulePaths, ":"), HieraConfigPath: remoteHieraConfigPath,
Sudo: !p.config.PreventSudo, ManifestFile: remoteManifestFile,
ModulePath: strings.Join(modulePaths, ":"),
Sudo: !p.config.PreventSudo,
}) })
if err != nil { if err != nil {
return err return err
@ -229,6 +260,22 @@ func (p *Provisioner) Cancel() {
os.Exit(0) os.Exit(0)
} }
func (p *Provisioner) uploadHieraConfig(ui packer.Ui, comm packer.Communicator) (string, error) {
ui.Message("Uploading hiera configuration...")
f, err := os.Open(p.config.HieraConfigPath)
if err != nil {
return "", err
}
defer f.Close()
path := fmt.Sprintf("%s/hiera.yaml", p.config.StagingDir)
if err := comm.Upload(path, f); err != nil {
return "", err
}
return path, nil
}
func (p *Provisioner) uploadManifests(ui packer.Ui, comm packer.Communicator) (string, error) { func (p *Provisioner) uploadManifests(ui packer.Ui, comm packer.Communicator) (string, error) {
// Create the remote manifests directory... // Create the remote manifests directory...
ui.Message("Uploading manifests...") ui.Message("Uploading manifests...")

View File

@ -26,6 +26,31 @@ func TestProvisioner_Impl(t *testing.T) {
} }
} }
func TestProvisionerPrepare_hieraConfigPath(t *testing.T) {
config := testConfig()
delete(config, "hiera_config_path")
p := new(Provisioner)
err := p.Prepare(config)
if err != nil {
t.Fatalf("err: %s", err)
}
// Test with a good one
tf, err := ioutil.TempFile("", "packer")
if err != nil {
t.Fatalf("error tempfile: %s", err)
}
defer os.Remove(tf.Name())
config["hiera_config_path"] = tf.Name()
p = new(Provisioner)
err = p.Prepare(config)
if err != nil {
t.Fatalf("err: %s", err)
}
}
func TestProvisionerPrepare_manifestFile(t *testing.T) { func TestProvisionerPrepare_manifestFile(t *testing.T) {
config := testConfig() config := testConfig()

View File

@ -54,6 +54,10 @@ Optional parameters:
[facts](http://puppetlabs.com/puppet/related-projects/facter) to make [facts](http://puppetlabs.com/puppet/related-projects/facter) to make
available when Puppet is running. available when Puppet is running.
* `hiera_config_path` (string) - The path to a local file with hiera
configuration to be uploaded to the remote machine. Hiera data directories
must be uploaded using the file provisioner separately.
* `module_paths` (array of strings) - This is an array of paths to module * `module_paths` (array of strings) - This is an array of paths to module
directories on your local filesystem. These will be uploaded to the remote directories on your local filesystem. These will be uploaded to the remote
machine. By default, this is empty. machine. By default, this is empty.
@ -78,6 +82,7 @@ for readability) to execute Puppet:
{{.FacterVars}}{{if .Sudo} sudo -E {{end}}puppet apply \ {{.FacterVars}}{{if .Sudo} sudo -E {{end}}puppet apply \
--verbose \ --verbose \
--modulepath='{{.ModulePath}}' \ --modulepath='{{.ModulePath}}' \
{{if .HasHieraConfigPath}}--hiera_config='{{.HieraConfigPath}}' {{end}} \
{{.ManifestFile}} {{.ManifestFile}}
``` ```
@ -87,6 +92,8 @@ can contain various template variables, defined below:
* `FacterVars` - Shell-friendly string of environmental variables used * `FacterVars` - Shell-friendly string of environmental variables used
to set custom facts configured for this provisioner. to set custom facts configured for this provisioner.
* `HasHieraConfigPath` - Boolean true if there is a hiera config path set.
* `HieraConfigPath` - The path to a hiera configuration file.
* `ManifestFile` - The path on the remote machine to the manifest file * `ManifestFile` - The path on the remote machine to the manifest file
for Puppet to use. for Puppet to use.
* `ModulePath` - The paths to the module directories. * `ModulePath` - The paths to the module directories.