From 4c537105efd296e296672a9b2134eaaa36287025 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 8 Sep 2013 22:59:43 -0700 Subject: [PATCH] provisioner/puppet-masterless: support custom facts --- provisioner/puppet-masterless/provisioner.go | 34 ++++++++++++++++++- .../puppet-masterless.html.markdown | 8 ++++- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/provisioner/puppet-masterless/provisioner.go b/provisioner/puppet-masterless/provisioner.go index 115198c53..c6a475a3d 100644 --- a/provisioner/puppet-masterless/provisioner.go +++ b/provisioner/puppet-masterless/provisioner.go @@ -19,6 +19,9 @@ type Config struct { // The command used to execute Puppet. ExecuteCommand string `mapstructure:"execute_command"` + // Additional facts to set when executing Puppet + Facter map[string]string + // An array of local paths of modules to upload. ModulePaths []string `mapstructure:"module_paths"` @@ -38,6 +41,7 @@ type Provisioner struct { } type ExecuteTemplate struct { + FacterVars string ModulePath string ManifestFile string Sudo bool @@ -60,7 +64,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { // Set some defaults if p.config.ExecuteCommand == "" { - p.config.ExecuteCommand = "{{if .Sudo}}sudo {{end}}puppet apply --verbose --modulepath='{{.ModulePath}}' {{.ManifestFile}}" + p.config.ExecuteCommand = "{{.FacterVars}}{{if .Sudo}} sudo -E {{end}}puppet apply --verbose --modulepath='{{.ModulePath}}' {{.ManifestFile}}" } if p.config.StagingDir == "" { @@ -107,6 +111,27 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { } } + newFacts := make(map[string]string) + for k, v := range p.config.Facter { + k, err := p.config.tpl.Process(k, nil) + if err != nil { + errs = packer.MultiErrorAppend(errs, + fmt.Errorf("Error processing facter key %s: %s", k, err)) + continue + } + + v, err := p.config.tpl.Process(v, nil) + if err != nil { + errs = packer.MultiErrorAppend(errs, + fmt.Errorf("Error processing facter value '%s': %s", v, err)) + continue + } + + newFacts[k] = v + } + + p.config.Facter = newFacts + // Validation if p.config.ManifestFile == "" { errs = packer.MultiErrorAppend(errs, @@ -165,8 +190,15 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { return fmt.Errorf("Error uploading manifests: %s", err) } + // Compile the facter variables + facterVars := make([]string, 0, len(p.config.Facter)) + for k, v := range p.config.Facter { + facterVars = append(facterVars, fmt.Sprintf("FACTER_%s='%s'", k, v)) + } + // Execute Puppet command, err := p.config.tpl.Process(p.config.ExecuteCommand, &ExecuteTemplate{ + FacterVars: strings.Join(facterVars, " "), ManifestFile: remoteManifestFile, ModulePath: strings.Join(modulePaths, ":"), Sudo: !p.config.PreventSudo, diff --git a/website/source/docs/provisioners/puppet-masterless.html.markdown b/website/source/docs/provisioners/puppet-masterless.html.markdown index 0535dc538..ee284c52e 100644 --- a/website/source/docs/provisioners/puppet-masterless.html.markdown +++ b/website/source/docs/provisioners/puppet-masterless.html.markdown @@ -50,6 +50,10 @@ Optional parameters: various [configuration template variables](/docs/templates/configuration-templates.html) available. See below for more information. +* `facter` (object, string keys and values) - Additonal + [facts](http://puppetlabs.com/puppet/related-projects/facter) to make + available when Puppet is running. + * `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 machine. By default, this is empty. @@ -71,7 +75,7 @@ By default, Packer uses the following command (broken across multiple lines for readability) to execute Puppet: ``` -{{if .Sudo}sudo {{end}}puppet apply \ +{{.FacterVars}}{{if .Sudo} sudo -E {{end}}puppet apply \ --verbose \ --modulepath='{{.ModulePath}}' \ {{.ManifestFile}} @@ -81,6 +85,8 @@ This command can be customized using the `execute_command` configuration. As you can see from the default value above, the value of this configuration can contain various template variables, defined below: +* `FacterVars` - Shell-friendly string of environmental variables used + to set custom facts configured for this provisioner. * `ManifestFile` - The path on the remote machine to the manifest file for Puppet to use. * `ModulePath` - The paths to the module directories.