From 5eb497a2c5ef548ecd8abb4181bad569e011fce4 Mon Sep 17 00:00:00 2001 From: Matthew Patton Date: Tue, 31 Jan 2017 05:09:04 -0500 Subject: [PATCH 01/21] reorder terms and define an intermediate variable (cherry picked from commit d0251f9741cf4d7659ecb4496d103f99a0e4184a) (cherry picked from commit dab1b903ad88af0e3e40168634c1eb227078b4eb) --- provisioner/puppet-masterless/provisioner.go | 29 ++++++--- provisioner/puppet-server/provisioner.go | 66 ++++++++++++++++++-- 2 files changed, 82 insertions(+), 13 deletions(-) diff --git a/provisioner/puppet-masterless/provisioner.go b/provisioner/puppet-masterless/provisioner.go index 4b01c84d3..c7360c646 100644 --- a/provisioner/puppet-masterless/provisioner.go +++ b/provisioner/puppet-masterless/provisioner.go @@ -26,6 +26,9 @@ type Config struct { // Additional arguments to pass when executing Puppet ExtraArguments []string `mapstructure:"extra_arguments"` + // The Guest OS Type (unix or windows) + GuestOSType string `mapstructure:"guest_os_type"` + // Additional facts to set when executing Puppet Facter map[string]string @@ -82,10 +85,11 @@ var guestOSTypeConfigs = map[string]guestOSTypeConfig{ `{{if ne .FacterVars ""}}{{.FacterVars}} {{end}}` + "{{if .Sudo}}sudo -E {{end}}" + `{{if ne .PuppetBinDir ""}}{{.PuppetBinDir}}/{{end}}` + - `puppet apply --verbose --modulepath='{{.ModulePath}}' ` + + "puppet apply --detailed-exitcodes " + + "{{if .Debug}}--debug {{end}}" + + `{{if ne .ModulePath ""}}--modulepath='{{.ModulePath}}' {{end}}` + `{{if ne .HieraConfigPath ""}}--hiera_config='{{.HieraConfigPath}}' {{end}}` + `{{if ne .ManifestDir ""}}--manifestdir='{{.ManifestDir}}' {{end}}` + - "--detailed-exitcodes " + `{{if ne .ExtraArguments ""}}{{.ExtraArguments}} {{end}}` + "{{.ManifestFile}}", facterVarsFmt: "FACTER_%s='%s'", @@ -97,10 +101,11 @@ var guestOSTypeConfigs = map[string]guestOSTypeConfig{ executeCommand: "cd {{.WorkingDir}} && " + "{{.FacterVars}} && " + `{{if ne .PuppetBinDir ""}}{{.PuppetBinDir}}/{{end}}` + - `puppet apply --verbose --modulepath='{{.ModulePath}}' ` + + "puppet apply --detailed-exitcodes " + + "{{if .Debug}}--debug {{end}}" + + `{{if ne .ModulePath ""}}--modulepath='{{.ModulePath}}' {{end}}` + `{{if ne .HieraConfigPath ""}}--hiera_config='{{.HieraConfigPath}}' {{end}}` + `{{if ne .ManifestDir ""}}--manifestdir='{{.ManifestDir}}' {{end}}` + - "--detailed-exitcodes " + `{{if ne .ExtraArguments ""}}{{.ExtraArguments}} {{end}}` + "{{.ManifestFile}}", facterVarsFmt: `SET "FACTER_%s=%s"`, @@ -124,6 +129,8 @@ type ExecuteTemplate struct { ManifestDir string PuppetBinDir string Sudo bool + WorkingDir string + Debug bool ExtraArguments string } @@ -134,6 +141,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { InterpolateFilter: &interpolate.RenderFilter{ Exclude: []string{ "execute_command", + "extra_arguments", }, }, }, raws...) @@ -286,8 +294,7 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { facterVars = append(facterVars, fmt.Sprintf(p.guestOSTypeConfig.facterVarsFmt, k, v)) } - // Execute Puppet - p.config.ctx.Data = &ExecuteTemplate{ + data := ExecuteTemplate{ FacterVars: strings.Join(facterVars, p.guestOSTypeConfig.facterVarsJoiner), HieraConfigPath: remoteHieraConfigPath, ManifestDir: remoteManifestDir, @@ -296,8 +303,16 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { PuppetBinDir: p.config.PuppetBinDir, Sudo: !p.config.PreventSudo, WorkingDir: p.config.WorkingDir, - ExtraArguments: strings.Join(p.config.ExtraArguments, " "), + ExtraArguments: "", } + + p.config.ctx.Data = &data + _ExtraArguments, err := interpolate.Render(strings.Join(p.config.ExtraArguments, " "), &p.config.ctx) + if err != nil { + return err + } + data.ExtraArguments = _ExtraArguments + command, err := interpolate.Render(p.config.ExecuteCommand, &p.config.ctx) if err != nil { return err diff --git a/provisioner/puppet-server/provisioner.go b/provisioner/puppet-server/provisioner.go index d7744952e..46263e72b 100644 --- a/provisioner/puppet-server/provisioner.go +++ b/provisioner/puppet-server/provisioner.go @@ -59,6 +59,9 @@ type Config struct { // The command used to execute Puppet. ExecuteCommand string `mapstructure:"execute_command"` + // Additional argument to pass when executing Puppet. + ExtraArguments []string `mapstructure:"extra_arguments"` + // The Guest OS Type (unix or windows) GuestOSType string `mapstructure:"guest_os_type"` @@ -77,9 +80,6 @@ type Config struct { // The hostname of the Puppet server. PuppetServer string `mapstructure:"puppet_server"` - // Additional options to be passed to `puppet agent`. - Options string `mapstructure:"options"` - // If true, `sudo` will NOT be used to execute Puppet. PreventSudo bool `mapstructure:"prevent_sudo"` @@ -95,6 +95,50 @@ type Config struct { IgnoreExitCodes bool `mapstructure:"ignore_exit_codes"` } +type guestOSTypeConfig struct { + tempDir string + stagingDir string + executeCommand string + facterVarsFmt string + facterVarsJoiner string +} + +var guestOSTypeConfigs = map[string]guestOSTypeConfig{ + provisioner.UnixOSType: { + tempDir: "/tmp", + stagingDir: "/tmp/packer-puppet-server", + executeCommand: "cd {{.WorkingDir}} && " + + "{{.FacterVars}}" + + "{{if .Sudo}}sudo -E {{end}}" + + `{{if ne .PuppetBinDir ""}}{{.PuppetBinDir}}/{{end}}` + + "puppet agent --onetime --no-daemonize --detailed-exitcodes " + + "{{if .Debug}}--debug {{end}}" + + `{{if ne .PuppetServer ""}}--server='{{.PuppetServer}}' {{end}}` + + `{{if ne .PuppetNode ""}}--certname={{.PuppetNode}} {{end}}` + + `{{if ne .ClientCertPath ""}}--certdir='{{.ClientCertPath}}' {{end}}` + + `{{if ne .ClientPrivateKeyPath ""}}--privatekeydir='{{.ClientPrivateKeyPath}}' {{end}}` + + `{{if ne .ExtraArguments ""}}{{.ExtraArguments}} {{end}}`, + facterVarsFmt: "FACTER_%s='%s'", + facterVarsJoiner: " ", + }, + provisioner.WindowsOSType: { + tempDir: path.filepath.ToSlash(os.Getenv("TEMP")), + stagingDir: path.filepath.ToSlash(os.Getenv("SYSTEMROOT")) + "/Temp/packer-puppet-server", + executeCommand: "cd {{.WorkingDir}} && " + + "{{.FacterVars}} " + + `{{if ne .PuppetBinDir ""}}{{.PuppetBinDir}}/{{end}}` + + "puppet agent --onetime --no-daemonize --detailed-exitcodes " + + "{{if .Debug}}--debug {{end}}" + + `{{if ne .PuppetServer ""}}--server='{{.PuppetServer}}' {{end}}` + + `{{if ne .PuppetNode ""}}--certname={{.PuppetNode}} {{end}}` + + `{{if ne .ClientCertPath ""}}--certdir='{{.ClientCertPath}}' {{end}}` + + `{{if ne .ClientPrivateKeyPath ""}}--privatekeydir='{{.ClientPrivateKeyPath}}' {{end}}` + + `{{if ne .ExtraArguments ""}}{{.ExtraArguments}} {{end}}`, + facterVarsFmt: `SET "FACTER_%s=%s"`, + facterVarsJoiner: " & ", + }, +} + type Provisioner struct { config Config guestOSTypeConfig guestOSTypeConfig @@ -107,7 +151,7 @@ type ExecuteTemplate struct { ClientPrivateKeyPath string PuppetNode string PuppetServer string - Options string + ExtraArguments string PuppetBinDir string Sudo bool } @@ -119,6 +163,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { InterpolateFilter: &interpolate.RenderFilter{ Exclude: []string{ "execute_command", + "extra_arguments", }, }, }, raws...) @@ -223,8 +268,7 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { facterVars = append(facterVars, fmt.Sprintf(p.guestOSTypeConfig.facterVarsFmt, k, v)) } - // Execute Puppet - p.config.ctx.Data = &ExecuteTemplate{ + data := ExecuteTemplate{ FacterVars: strings.Join(facterVars, p.guestOSTypeConfig.facterVarsJoiner), ClientCertPath: remoteClientCertPath, ClientPrivateKeyPath: remoteClientPrivateKeyPath, @@ -233,7 +277,17 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { Options: p.config.Options, PuppetBinDir: p.config.PuppetBinDir, Sudo: !p.config.PreventSudo, + WorkingDir: p.config.WorkingDir, + ExtraArguments: "", + } + + p.config.ctx.Data = &data + _ExtraArguments, err := interpolate.Render(strings.Join(p.config.ExtraArguments, " "), &p.config.ctx) + if err != nil { + return err } + data.ExtraArguments = _ExtraArguments + command, err := interpolate.Render(p.config.ExecuteCommand, &p.config.ctx) if err != nil { return err From 913ad33a11aa93247be0ab294a2c62b11cf917e0 Mon Sep 17 00:00:00 2001 From: Matthew Patton Date: Fri, 27 Apr 2018 20:40:13 -0400 Subject: [PATCH 02/21] standardize across both puppet-{masterless,server} --- provisioner/puppet-masterless/provisioner.go | 32 +++++++++++--------- provisioner/puppet-server/provisioner.go | 18 ++++++++--- 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/provisioner/puppet-masterless/provisioner.go b/provisioner/puppet-masterless/provisioner.go index c7360c646..959104ab4 100644 --- a/provisioner/puppet-masterless/provisioner.go +++ b/provisioner/puppet-masterless/provisioner.go @@ -71,8 +71,9 @@ type Config struct { } type guestOSTypeConfig struct { + tempDir string stagingDir string - executeCommand string + executeCommand string facterVarsFmt string facterVarsJoiner string modulePathJoiner string @@ -80,6 +81,8 @@ type guestOSTypeConfig struct { var guestOSTypeConfigs = map[string]guestOSTypeConfig{ provisioner.UnixOSType: { + #FIXME assumes both Packer host and target are same OS + tempDir: "/tmp", stagingDir: "/tmp/packer-puppet-masterless", executeCommand: "cd {{.WorkingDir}} && " + `{{if ne .FacterVars ""}}{{.FacterVars}} {{end}}` + @@ -97,9 +100,11 @@ var guestOSTypeConfigs = map[string]guestOSTypeConfig{ modulePathJoiner: ":", }, provisioner.WindowsOSType: { - stagingDir: "C:/Windows/Temp/packer-puppet-masterless", + #FIXME assumes both Packer host and target are same OS + tempDir: path.filepath.ToSlash(os.Getenv("TEMP")), + stagingDir: path.filepath.ToSlash(os.Getenv("SYSTEMROOT")) + "/Temp/packer-puppet-masterless", executeCommand: "cd {{.WorkingDir}} && " + - "{{.FacterVars}} && " + + `{{if ne .FacterVars ""}}{{.FacterVars}} && {{end}}` + `{{if ne .PuppetBinDir ""}}{{.PuppetBinDir}}/{{end}}` + "puppet apply --detailed-exitcodes " + "{{if .Debug}}--debug {{end}}" + @@ -121,24 +126,23 @@ type Provisioner struct { } type ExecuteTemplate struct { - WorkingDir string - FacterVars string + FacterVars string HieraConfigPath string - ModulePath string - ManifestFile string - ManifestDir string - PuppetBinDir string - Sudo bool - WorkingDir string - Debug bool - ExtraArguments string + ModulePath string + ManifestFile string + ManifestDir string + PuppetBinDir string + Sudo bool + WorkingDir string + Debug bool + ExtraArguments string } func (p *Provisioner) Prepare(raws ...interface{}) error { err := config.Decode(&p.config, &config.DecodeOpts{ Interpolate: true, InterpolateContext: &p.config.ctx, - InterpolateFilter: &interpolate.RenderFilter{ + InterpolateFilter: &interpolate.RenderFilter{ Exclude: []string{ "execute_command", "extra_arguments", diff --git a/provisioner/puppet-server/provisioner.go b/provisioner/puppet-server/provisioner.go index 46263e72b..0ba1cfb7d 100644 --- a/provisioner/puppet-server/provisioner.go +++ b/provisioner/puppet-server/provisioner.go @@ -87,6 +87,10 @@ type Config struct { // permissions in this directory. StagingDir string `mapstructure:"staging_dir"` + // The directory from which the command will be executed. + // Packer requires the directory to exist when running puppet. + WorkingDir string `mapstructure:"working_directory"` + // The directory that contains the puppet binary. // E.g. if it can't be found on the standard path. PuppetBinDir string `mapstructure:"puppet_bin_dir"` @@ -105,10 +109,11 @@ type guestOSTypeConfig struct { var guestOSTypeConfigs = map[string]guestOSTypeConfig{ provisioner.UnixOSType: { + #FIXME assumes both Packer host and target are same OS tempDir: "/tmp", stagingDir: "/tmp/packer-puppet-server", executeCommand: "cd {{.WorkingDir}} && " + - "{{.FacterVars}}" + + `{{if ne .FacterVars ""}}{{.FacterVars}} {{end}}` + "{{if .Sudo}}sudo -E {{end}}" + `{{if ne .PuppetBinDir ""}}{{.PuppetBinDir}}/{{end}}` + "puppet agent --onetime --no-daemonize --detailed-exitcodes " + @@ -122,10 +127,11 @@ var guestOSTypeConfigs = map[string]guestOSTypeConfig{ facterVarsJoiner: " ", }, provisioner.WindowsOSType: { + #FIXME assumes both Packer host and target are same OS tempDir: path.filepath.ToSlash(os.Getenv("TEMP")), stagingDir: path.filepath.ToSlash(os.Getenv("SYSTEMROOT")) + "/Temp/packer-puppet-server", executeCommand: "cd {{.WorkingDir}} && " + - "{{.FacterVars}} " + + `{{if ne .FacterVars ""}}{{.FacterVars}} && {{end}}` + `{{if ne .PuppetBinDir ""}}{{.PuppetBinDir}}/{{end}}` + "puppet agent --onetime --no-daemonize --detailed-exitcodes " + "{{if .Debug}}--debug {{end}}" + @@ -149,18 +155,20 @@ type ExecuteTemplate struct { FacterVars string ClientCertPath string ClientPrivateKeyPath string - PuppetNode string + PuppetNode string PuppetServer string - ExtraArguments string PuppetBinDir string Sudo bool + WorkingDir string + Debug bool + ExtraArguments string } func (p *Provisioner) Prepare(raws ...interface{}) error { err := config.Decode(&p.config, &config.DecodeOpts{ Interpolate: true, InterpolateContext: &p.config.ctx, - InterpolateFilter: &interpolate.RenderFilter{ + InterpolateFilter: &interpolate.RenderFilter{ Exclude: []string{ "execute_command", "extra_arguments", From 0fa037d2970e86723c858ac1b373b590d55a80b6 Mon Sep 17 00:00:00 2001 From: Matthew Patton Date: Fri, 27 Apr 2018 21:38:51 -0400 Subject: [PATCH 03/21] move comments outside of datastructure --- provisioner/puppet-masterless/provisioner.go | 3 +-- provisioner/puppet-server/provisioner.go | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/provisioner/puppet-masterless/provisioner.go b/provisioner/puppet-masterless/provisioner.go index 959104ab4..57a5311c7 100644 --- a/provisioner/puppet-masterless/provisioner.go +++ b/provisioner/puppet-masterless/provisioner.go @@ -79,9 +79,9 @@ type guestOSTypeConfig struct { modulePathJoiner string } +#FIXME assumes both Packer host and target are same OS var guestOSTypeConfigs = map[string]guestOSTypeConfig{ provisioner.UnixOSType: { - #FIXME assumes both Packer host and target are same OS tempDir: "/tmp", stagingDir: "/tmp/packer-puppet-masterless", executeCommand: "cd {{.WorkingDir}} && " + @@ -100,7 +100,6 @@ var guestOSTypeConfigs = map[string]guestOSTypeConfig{ modulePathJoiner: ":", }, provisioner.WindowsOSType: { - #FIXME assumes both Packer host and target are same OS tempDir: path.filepath.ToSlash(os.Getenv("TEMP")), stagingDir: path.filepath.ToSlash(os.Getenv("SYSTEMROOT")) + "/Temp/packer-puppet-masterless", executeCommand: "cd {{.WorkingDir}} && " + diff --git a/provisioner/puppet-server/provisioner.go b/provisioner/puppet-server/provisioner.go index 0ba1cfb7d..485a252bd 100644 --- a/provisioner/puppet-server/provisioner.go +++ b/provisioner/puppet-server/provisioner.go @@ -107,9 +107,9 @@ type guestOSTypeConfig struct { facterVarsJoiner string } +#FIXME assumes both Packer host and target are same OS var guestOSTypeConfigs = map[string]guestOSTypeConfig{ provisioner.UnixOSType: { - #FIXME assumes both Packer host and target are same OS tempDir: "/tmp", stagingDir: "/tmp/packer-puppet-server", executeCommand: "cd {{.WorkingDir}} && " + @@ -127,7 +127,6 @@ var guestOSTypeConfigs = map[string]guestOSTypeConfig{ facterVarsJoiner: " ", }, provisioner.WindowsOSType: { - #FIXME assumes both Packer host and target are same OS tempDir: path.filepath.ToSlash(os.Getenv("TEMP")), stagingDir: path.filepath.ToSlash(os.Getenv("SYSTEMROOT")) + "/Temp/packer-puppet-server", executeCommand: "cd {{.WorkingDir}} && " + From 25252f083eb753b9e221568aed904a86e86152a9 Mon Sep 17 00:00:00 2001 From: Matthew Patton Date: Fri, 27 Apr 2018 22:33:54 -0400 Subject: [PATCH 04/21] remove duplicated section --- provisioner/puppet-server/provisioner.go | 38 ------------------------ 1 file changed, 38 deletions(-) diff --git a/provisioner/puppet-server/provisioner.go b/provisioner/puppet-server/provisioner.go index 485a252bd..19066faa6 100644 --- a/provisioner/puppet-server/provisioner.go +++ b/provisioner/puppet-server/provisioner.go @@ -14,44 +14,6 @@ import ( "github.com/hashicorp/packer/template/interpolate" ) -type guestOSTypeConfig struct { - executeCommand string - facterVarsFmt string - facterVarsJoiner string - stagingDir string -} - -var guestOSTypeConfigs = map[string]guestOSTypeConfig{ - provisioner.UnixOSType: { - executeCommand: "{{.FacterVars}} {{if .Sudo}}sudo -E {{end}}" + - "{{if ne .PuppetBinDir \"\"}}{{.PuppetBinDir}}/{{end}}puppet agent " + - "--onetime --no-daemonize " + - "{{if ne .PuppetServer \"\"}}--server='{{.PuppetServer}}' {{end}}" + - "{{if ne .Options \"\"}}{{.Options}} {{end}}" + - "{{if ne .PuppetNode \"\"}}--certname={{.PuppetNode}} {{end}}" + - "{{if ne .ClientCertPath \"\"}}--certdir='{{.ClientCertPath}}' {{end}}" + - "{{if ne .ClientPrivateKeyPath \"\"}}--privatekeydir='{{.ClientPrivateKeyPath}}' {{end}}" + - "--detailed-exitcodes", - facterVarsFmt: "FACTER_%s='%s'", - facterVarsJoiner: " ", - stagingDir: "/tmp/packer-puppet-server", - }, - provisioner.WindowsOSType: { - executeCommand: "{{.FacterVars}} " + - "{{if ne .PuppetBinDir \"\"}}{{.PuppetBinDir}}/{{end}}puppet agent " + - "--onetime --no-daemonize " + - "{{if ne .PuppetServer \"\"}}--server='{{.PuppetServer}}' {{end}}" + - "{{if ne .Options \"\"}}{{.Options}} {{end}}" + - "{{if ne .PuppetNode \"\"}}--certname={{.PuppetNode}} {{end}}" + - "{{if ne .ClientCertPath \"\"}}--certdir='{{.ClientCertPath}}' {{end}}" + - "{{if ne .ClientPrivateKeyPath \"\"}}--privatekeydir='{{.ClientPrivateKeyPath}}' {{end}}" + - "--detailed-exitcodes", - facterVarsFmt: "SET \"FACTER_%s=%s\"", - facterVarsJoiner: " & ", - stagingDir: "C:/Windows/Temp/packer-puppet-server", - }, -} - type Config struct { common.PackerConfig `mapstructure:",squash"` ctx interpolate.Context From bb1aed5264ff13ceaf029ea044f28ff2b81dce04 Mon Sep 17 00:00:00 2001 From: Matthew Patton Date: Fri, 27 Apr 2018 22:34:15 -0400 Subject: [PATCH 05/21] fix line-endings --- .gitattributes | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index 7230f36f4..07e7d50e4 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,3 @@ -common/test-fixtures/root/* eol=lf \ No newline at end of file +common/test-fixtures/root/* eol=lf +*.go eol=lf From d57842e06d764a7a01d6d3772c15cd41f310f216 Mon Sep 17 00:00:00 2001 From: Matthew Patton Date: Fri, 27 Apr 2018 22:44:16 -0400 Subject: [PATCH 06/21] Golang doesn't use C-style comments --- provisioner/puppet-masterless/provisioner.go | 2 +- provisioner/puppet-server/provisioner.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/provisioner/puppet-masterless/provisioner.go b/provisioner/puppet-masterless/provisioner.go index 57a5311c7..347a20de9 100644 --- a/provisioner/puppet-masterless/provisioner.go +++ b/provisioner/puppet-masterless/provisioner.go @@ -79,7 +79,7 @@ type guestOSTypeConfig struct { modulePathJoiner string } -#FIXME assumes both Packer host and target are same OS +// FIXME assumes both Packer host and target are same OS var guestOSTypeConfigs = map[string]guestOSTypeConfig{ provisioner.UnixOSType: { tempDir: "/tmp", diff --git a/provisioner/puppet-server/provisioner.go b/provisioner/puppet-server/provisioner.go index 19066faa6..20ff54243 100644 --- a/provisioner/puppet-server/provisioner.go +++ b/provisioner/puppet-server/provisioner.go @@ -69,7 +69,7 @@ type guestOSTypeConfig struct { facterVarsJoiner string } -#FIXME assumes both Packer host and target are same OS +// FIXME assumes both Packer host and target are same OS var guestOSTypeConfigs = map[string]guestOSTypeConfig{ provisioner.UnixOSType: { tempDir: "/tmp", From 2450e57fbee838f70a62d1dc0252c3eeb2fdc815 Mon Sep 17 00:00:00 2001 From: Matthew Patton Date: Fri, 27 Apr 2018 22:51:48 -0400 Subject: [PATCH 07/21] run gofmt for alignment and whitespace management --- provisioner/puppet-masterless/provisioner.go | 26 ++++++++++---------- provisioner/puppet-server/provisioner.go | 8 +++--- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/provisioner/puppet-masterless/provisioner.go b/provisioner/puppet-masterless/provisioner.go index 347a20de9..c7bb6ddc2 100644 --- a/provisioner/puppet-masterless/provisioner.go +++ b/provisioner/puppet-masterless/provisioner.go @@ -73,7 +73,7 @@ type Config struct { type guestOSTypeConfig struct { tempDir string stagingDir string - executeCommand string + executeCommand string facterVarsFmt string facterVarsJoiner string modulePathJoiner string @@ -82,7 +82,7 @@ type guestOSTypeConfig struct { // FIXME assumes both Packer host and target are same OS var guestOSTypeConfigs = map[string]guestOSTypeConfig{ provisioner.UnixOSType: { - tempDir: "/tmp", + tempDir: "/tmp", stagingDir: "/tmp/packer-puppet-masterless", executeCommand: "cd {{.WorkingDir}} && " + `{{if ne .FacterVars ""}}{{.FacterVars}} {{end}}` + @@ -100,7 +100,7 @@ var guestOSTypeConfigs = map[string]guestOSTypeConfig{ modulePathJoiner: ":", }, provisioner.WindowsOSType: { - tempDir: path.filepath.ToSlash(os.Getenv("TEMP")), + tempDir: path.filepath.ToSlash(os.Getenv("TEMP")), stagingDir: path.filepath.ToSlash(os.Getenv("SYSTEMROOT")) + "/Temp/packer-puppet-masterless", executeCommand: "cd {{.WorkingDir}} && " + `{{if ne .FacterVars ""}}{{.FacterVars}} && {{end}}` + @@ -125,23 +125,23 @@ type Provisioner struct { } type ExecuteTemplate struct { - FacterVars string + FacterVars string HieraConfigPath string - ModulePath string - ManifestFile string - ManifestDir string - PuppetBinDir string - Sudo bool - WorkingDir string - Debug bool - ExtraArguments string + ModulePath string + ManifestFile string + ManifestDir string + PuppetBinDir string + Sudo bool + WorkingDir string + Debug bool + ExtraArguments string } func (p *Provisioner) Prepare(raws ...interface{}) error { err := config.Decode(&p.config, &config.DecodeOpts{ Interpolate: true, InterpolateContext: &p.config.ctx, - InterpolateFilter: &interpolate.RenderFilter{ + InterpolateFilter: &interpolate.RenderFilter{ Exclude: []string{ "execute_command", "extra_arguments", diff --git a/provisioner/puppet-server/provisioner.go b/provisioner/puppet-server/provisioner.go index 20ff54243..146d40f9e 100644 --- a/provisioner/puppet-server/provisioner.go +++ b/provisioner/puppet-server/provisioner.go @@ -72,7 +72,7 @@ type guestOSTypeConfig struct { // FIXME assumes both Packer host and target are same OS var guestOSTypeConfigs = map[string]guestOSTypeConfig{ provisioner.UnixOSType: { - tempDir: "/tmp", + tempDir: "/tmp", stagingDir: "/tmp/packer-puppet-server", executeCommand: "cd {{.WorkingDir}} && " + `{{if ne .FacterVars ""}}{{.FacterVars}} {{end}}` + @@ -89,7 +89,7 @@ var guestOSTypeConfigs = map[string]guestOSTypeConfig{ facterVarsJoiner: " ", }, provisioner.WindowsOSType: { - tempDir: path.filepath.ToSlash(os.Getenv("TEMP")), + tempDir: path.filepath.ToSlash(os.Getenv("TEMP")), stagingDir: path.filepath.ToSlash(os.Getenv("SYSTEMROOT")) + "/Temp/packer-puppet-server", executeCommand: "cd {{.WorkingDir}} && " + `{{if ne .FacterVars ""}}{{.FacterVars}} && {{end}}` + @@ -116,7 +116,7 @@ type ExecuteTemplate struct { FacterVars string ClientCertPath string ClientPrivateKeyPath string - PuppetNode string + PuppetNode string PuppetServer string PuppetBinDir string Sudo bool @@ -129,7 +129,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { err := config.Decode(&p.config, &config.DecodeOpts{ Interpolate: true, InterpolateContext: &p.config.ctx, - InterpolateFilter: &interpolate.RenderFilter{ + InterpolateFilter: &interpolate.RenderFilter{ Exclude: []string{ "execute_command", "extra_arguments", From 422b4a073ec8e2b64cfb0630e25aa9e326427f77 Mon Sep 17 00:00:00 2001 From: Matthew Patton Date: Fri, 27 Apr 2018 23:22:52 -0400 Subject: [PATCH 08/21] remove danling "options" and fix class reference --- provisioner/puppet-masterless/provisioner.go | 7 ++----- provisioner/puppet-server/provisioner.go | 6 +++--- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/provisioner/puppet-masterless/provisioner.go b/provisioner/puppet-masterless/provisioner.go index c7bb6ddc2..61494c9d7 100644 --- a/provisioner/puppet-masterless/provisioner.go +++ b/provisioner/puppet-masterless/provisioner.go @@ -65,9 +65,6 @@ type Config struct { // If true, packer will ignore all exit-codes from a puppet run IgnoreExitCodes bool `mapstructure:"ignore_exit_codes"` - - // The Guest OS Type (unix or windows) - GuestOSType string `mapstructure:"guest_os_type"` } type guestOSTypeConfig struct { @@ -100,8 +97,8 @@ var guestOSTypeConfigs = map[string]guestOSTypeConfig{ modulePathJoiner: ":", }, provisioner.WindowsOSType: { - tempDir: path.filepath.ToSlash(os.Getenv("TEMP")), - stagingDir: path.filepath.ToSlash(os.Getenv("SYSTEMROOT")) + "/Temp/packer-puppet-masterless", + tempDir: filepath.ToSlash(os.Getenv("TEMP")), + stagingDir: filepath.ToSlash(os.Getenv("SYSTEMROOT")) + "/Temp/packer-puppet-masterless", executeCommand: "cd {{.WorkingDir}} && " + `{{if ne .FacterVars ""}}{{.FacterVars}} && {{end}}` + `{{if ne .PuppetBinDir ""}}{{.PuppetBinDir}}/{{end}}` + diff --git a/provisioner/puppet-server/provisioner.go b/provisioner/puppet-server/provisioner.go index 146d40f9e..8bd29a40e 100644 --- a/provisioner/puppet-server/provisioner.go +++ b/provisioner/puppet-server/provisioner.go @@ -5,6 +5,7 @@ package puppetserver import ( "fmt" "os" + "path/filepath" "strings" "github.com/hashicorp/packer/common" @@ -89,8 +90,8 @@ var guestOSTypeConfigs = map[string]guestOSTypeConfig{ facterVarsJoiner: " ", }, provisioner.WindowsOSType: { - tempDir: path.filepath.ToSlash(os.Getenv("TEMP")), - stagingDir: path.filepath.ToSlash(os.Getenv("SYSTEMROOT")) + "/Temp/packer-puppet-server", + tempDir: filepath.ToSlash(os.Getenv("TEMP")), + stagingDir: filepath.ToSlash(os.Getenv("SYSTEMROOT")) + "/Temp/packer-puppet-server", executeCommand: "cd {{.WorkingDir}} && " + `{{if ne .FacterVars ""}}{{.FacterVars}} && {{end}}` + `{{if ne .PuppetBinDir ""}}{{.PuppetBinDir}}/{{end}}` + @@ -243,7 +244,6 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { ClientPrivateKeyPath: remoteClientPrivateKeyPath, PuppetNode: p.config.PuppetNode, PuppetServer: p.config.PuppetServer, - Options: p.config.Options, PuppetBinDir: p.config.PuppetBinDir, Sudo: !p.config.PreventSudo, WorkingDir: p.config.WorkingDir, From 1aa7358c13ebb825d58d325276cb676a5e398e23 Mon Sep 17 00:00:00 2001 From: Matthew Patton Date: Fri, 27 Apr 2018 23:41:31 -0400 Subject: [PATCH 09/21] syncronize tests to new command structure --- provisioner/puppet-masterless/provisioner_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/provisioner/puppet-masterless/provisioner_test.go b/provisioner/puppet-masterless/provisioner_test.go index dd6725768..fe64f28bd 100644 --- a/provisioner/puppet-masterless/provisioner_test.go +++ b/provisioner/puppet-masterless/provisioner_test.go @@ -53,7 +53,7 @@ func TestGuestOSConfig_empty_unix(t *testing.T) { } expected := "cd /tmp/packer-puppet-masterless && " + - "sudo -E puppet apply --verbose --modulepath='' --detailed-exitcodes /r/m/f" + "sudo -E puppet apply --detailed-exitcodes /r/m/f" assert.Equal(t, expected, command) } @@ -89,8 +89,8 @@ func TestGuestOSConfig_full_unix(t *testing.T) { expected := "cd /tmp/packer-puppet-masterless && FACTER_lhs='rhs' FACTER_foo='bar' " + "sudo -E puppet apply " + - "--verbose --modulepath='/m/p:/a/b' --hiera_config='/h/c/p' " + - "--manifestdir='/r/m/d' --detailed-exitcodes /r/m/f" + "--detailed-exitcodes --modulepath='/m/p:/a/b' --hiera_config='/h/c/p' " + + "--manifestdir='/r/m/d' /r/m/f" assert.Equal(t, expected, command) } @@ -115,7 +115,7 @@ func TestGuestOSConfig_empty_windows(t *testing.T) { t.Fatalf("err: %s", err) } - expected := "cd C:/Windows/Temp/packer-puppet-masterless && && puppet apply --verbose --modulepath='' --detailed-exitcodes /r/m/f" + expected := "cd C:/Windows/Temp/packer-puppet-masterless && puppet apply --detailed-exitcodes /r/m/f" assert.Equal(t, expected, command) } @@ -152,8 +152,8 @@ func TestGuestOSConfig_full_windows(t *testing.T) { expected := "cd C:/Windows/Temp/packer-puppet-masterless && " + "SET \"FACTER_lhs=rhs\" & SET \"FACTER_foo=bar\" && " + - "puppet apply --verbose --modulepath='/m/p;/a/b' --hiera_config='/h/c/p' " + - "--manifestdir='/r/m/d' --detailed-exitcodes /r/m/f" + "puppet apply --detailed-exitcodes --modulepath='/m/p;/a/b' --hiera_config='/h/c/p' " + + "--manifestdir='/r/m/d' /r/m/f" assert.Equal(t, expected, command) } From 8bb7798ea7b6556dc1efcf7e742dc3d4a1d112c3 Mon Sep 17 00:00:00 2001 From: Matthew Patton Date: Fri, 27 Apr 2018 20:40:13 -0400 Subject: [PATCH 10/21] standardize across both puppet-{masterless,server} move comments outside of datastructure remove duplicated section fix line-endings Golang doesn't use C-style comments run gofmt for alignment and whitespace management remove danling "options" and fix class reference syncronize tests to new command structure --- .gitattributes | 3 +- provisioner/puppet-masterless/provisioner.go | 12 ++-- .../puppet-masterless/provisioner_test.go | 12 ++-- provisioner/puppet-server/provisioner.go | 59 +++++-------------- 4 files changed, 28 insertions(+), 58 deletions(-) diff --git a/.gitattributes b/.gitattributes index 7230f36f4..07e7d50e4 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,3 @@ -common/test-fixtures/root/* eol=lf \ No newline at end of file +common/test-fixtures/root/* eol=lf +*.go eol=lf diff --git a/provisioner/puppet-masterless/provisioner.go b/provisioner/puppet-masterless/provisioner.go index c7360c646..61494c9d7 100644 --- a/provisioner/puppet-masterless/provisioner.go +++ b/provisioner/puppet-masterless/provisioner.go @@ -65,12 +65,10 @@ type Config struct { // If true, packer will ignore all exit-codes from a puppet run IgnoreExitCodes bool `mapstructure:"ignore_exit_codes"` - - // The Guest OS Type (unix or windows) - GuestOSType string `mapstructure:"guest_os_type"` } type guestOSTypeConfig struct { + tempDir string stagingDir string executeCommand string facterVarsFmt string @@ -78,8 +76,10 @@ type guestOSTypeConfig struct { modulePathJoiner string } +// FIXME assumes both Packer host and target are same OS var guestOSTypeConfigs = map[string]guestOSTypeConfig{ provisioner.UnixOSType: { + tempDir: "/tmp", stagingDir: "/tmp/packer-puppet-masterless", executeCommand: "cd {{.WorkingDir}} && " + `{{if ne .FacterVars ""}}{{.FacterVars}} {{end}}` + @@ -97,9 +97,10 @@ var guestOSTypeConfigs = map[string]guestOSTypeConfig{ modulePathJoiner: ":", }, provisioner.WindowsOSType: { - stagingDir: "C:/Windows/Temp/packer-puppet-masterless", + tempDir: filepath.ToSlash(os.Getenv("TEMP")), + stagingDir: filepath.ToSlash(os.Getenv("SYSTEMROOT")) + "/Temp/packer-puppet-masterless", executeCommand: "cd {{.WorkingDir}} && " + - "{{.FacterVars}} && " + + `{{if ne .FacterVars ""}}{{.FacterVars}} && {{end}}` + `{{if ne .PuppetBinDir ""}}{{.PuppetBinDir}}/{{end}}` + "puppet apply --detailed-exitcodes " + "{{if .Debug}}--debug {{end}}" + @@ -121,7 +122,6 @@ type Provisioner struct { } type ExecuteTemplate struct { - WorkingDir string FacterVars string HieraConfigPath string ModulePath string diff --git a/provisioner/puppet-masterless/provisioner_test.go b/provisioner/puppet-masterless/provisioner_test.go index dd6725768..fe64f28bd 100644 --- a/provisioner/puppet-masterless/provisioner_test.go +++ b/provisioner/puppet-masterless/provisioner_test.go @@ -53,7 +53,7 @@ func TestGuestOSConfig_empty_unix(t *testing.T) { } expected := "cd /tmp/packer-puppet-masterless && " + - "sudo -E puppet apply --verbose --modulepath='' --detailed-exitcodes /r/m/f" + "sudo -E puppet apply --detailed-exitcodes /r/m/f" assert.Equal(t, expected, command) } @@ -89,8 +89,8 @@ func TestGuestOSConfig_full_unix(t *testing.T) { expected := "cd /tmp/packer-puppet-masterless && FACTER_lhs='rhs' FACTER_foo='bar' " + "sudo -E puppet apply " + - "--verbose --modulepath='/m/p:/a/b' --hiera_config='/h/c/p' " + - "--manifestdir='/r/m/d' --detailed-exitcodes /r/m/f" + "--detailed-exitcodes --modulepath='/m/p:/a/b' --hiera_config='/h/c/p' " + + "--manifestdir='/r/m/d' /r/m/f" assert.Equal(t, expected, command) } @@ -115,7 +115,7 @@ func TestGuestOSConfig_empty_windows(t *testing.T) { t.Fatalf("err: %s", err) } - expected := "cd C:/Windows/Temp/packer-puppet-masterless && && puppet apply --verbose --modulepath='' --detailed-exitcodes /r/m/f" + expected := "cd C:/Windows/Temp/packer-puppet-masterless && puppet apply --detailed-exitcodes /r/m/f" assert.Equal(t, expected, command) } @@ -152,8 +152,8 @@ func TestGuestOSConfig_full_windows(t *testing.T) { expected := "cd C:/Windows/Temp/packer-puppet-masterless && " + "SET \"FACTER_lhs=rhs\" & SET \"FACTER_foo=bar\" && " + - "puppet apply --verbose --modulepath='/m/p;/a/b' --hiera_config='/h/c/p' " + - "--manifestdir='/r/m/d' --detailed-exitcodes /r/m/f" + "puppet apply --detailed-exitcodes --modulepath='/m/p;/a/b' --hiera_config='/h/c/p' " + + "--manifestdir='/r/m/d' /r/m/f" assert.Equal(t, expected, command) } diff --git a/provisioner/puppet-server/provisioner.go b/provisioner/puppet-server/provisioner.go index 46263e72b..8bd29a40e 100644 --- a/provisioner/puppet-server/provisioner.go +++ b/provisioner/puppet-server/provisioner.go @@ -5,6 +5,7 @@ package puppetserver import ( "fmt" "os" + "path/filepath" "strings" "github.com/hashicorp/packer/common" @@ -14,44 +15,6 @@ import ( "github.com/hashicorp/packer/template/interpolate" ) -type guestOSTypeConfig struct { - executeCommand string - facterVarsFmt string - facterVarsJoiner string - stagingDir string -} - -var guestOSTypeConfigs = map[string]guestOSTypeConfig{ - provisioner.UnixOSType: { - executeCommand: "{{.FacterVars}} {{if .Sudo}}sudo -E {{end}}" + - "{{if ne .PuppetBinDir \"\"}}{{.PuppetBinDir}}/{{end}}puppet agent " + - "--onetime --no-daemonize " + - "{{if ne .PuppetServer \"\"}}--server='{{.PuppetServer}}' {{end}}" + - "{{if ne .Options \"\"}}{{.Options}} {{end}}" + - "{{if ne .PuppetNode \"\"}}--certname={{.PuppetNode}} {{end}}" + - "{{if ne .ClientCertPath \"\"}}--certdir='{{.ClientCertPath}}' {{end}}" + - "{{if ne .ClientPrivateKeyPath \"\"}}--privatekeydir='{{.ClientPrivateKeyPath}}' {{end}}" + - "--detailed-exitcodes", - facterVarsFmt: "FACTER_%s='%s'", - facterVarsJoiner: " ", - stagingDir: "/tmp/packer-puppet-server", - }, - provisioner.WindowsOSType: { - executeCommand: "{{.FacterVars}} " + - "{{if ne .PuppetBinDir \"\"}}{{.PuppetBinDir}}/{{end}}puppet agent " + - "--onetime --no-daemonize " + - "{{if ne .PuppetServer \"\"}}--server='{{.PuppetServer}}' {{end}}" + - "{{if ne .Options \"\"}}{{.Options}} {{end}}" + - "{{if ne .PuppetNode \"\"}}--certname={{.PuppetNode}} {{end}}" + - "{{if ne .ClientCertPath \"\"}}--certdir='{{.ClientCertPath}}' {{end}}" + - "{{if ne .ClientPrivateKeyPath \"\"}}--privatekeydir='{{.ClientPrivateKeyPath}}' {{end}}" + - "--detailed-exitcodes", - facterVarsFmt: "SET \"FACTER_%s=%s\"", - facterVarsJoiner: " & ", - stagingDir: "C:/Windows/Temp/packer-puppet-server", - }, -} - type Config struct { common.PackerConfig `mapstructure:",squash"` ctx interpolate.Context @@ -87,6 +50,10 @@ type Config struct { // permissions in this directory. StagingDir string `mapstructure:"staging_dir"` + // The directory from which the command will be executed. + // Packer requires the directory to exist when running puppet. + WorkingDir string `mapstructure:"working_directory"` + // The directory that contains the puppet binary. // E.g. if it can't be found on the standard path. PuppetBinDir string `mapstructure:"puppet_bin_dir"` @@ -103,12 +70,13 @@ type guestOSTypeConfig struct { facterVarsJoiner string } +// FIXME assumes both Packer host and target are same OS var guestOSTypeConfigs = map[string]guestOSTypeConfig{ provisioner.UnixOSType: { - tempDir: "/tmp", + tempDir: "/tmp", stagingDir: "/tmp/packer-puppet-server", executeCommand: "cd {{.WorkingDir}} && " + - "{{.FacterVars}}" + + `{{if ne .FacterVars ""}}{{.FacterVars}} {{end}}` + "{{if .Sudo}}sudo -E {{end}}" + `{{if ne .PuppetBinDir ""}}{{.PuppetBinDir}}/{{end}}` + "puppet agent --onetime --no-daemonize --detailed-exitcodes " + @@ -122,10 +90,10 @@ var guestOSTypeConfigs = map[string]guestOSTypeConfig{ facterVarsJoiner: " ", }, provisioner.WindowsOSType: { - tempDir: path.filepath.ToSlash(os.Getenv("TEMP")), - stagingDir: path.filepath.ToSlash(os.Getenv("SYSTEMROOT")) + "/Temp/packer-puppet-server", + tempDir: filepath.ToSlash(os.Getenv("TEMP")), + stagingDir: filepath.ToSlash(os.Getenv("SYSTEMROOT")) + "/Temp/packer-puppet-server", executeCommand: "cd {{.WorkingDir}} && " + - "{{.FacterVars}} " + + `{{if ne .FacterVars ""}}{{.FacterVars}} && {{end}}` + `{{if ne .PuppetBinDir ""}}{{.PuppetBinDir}}/{{end}}` + "puppet agent --onetime --no-daemonize --detailed-exitcodes " + "{{if .Debug}}--debug {{end}}" + @@ -151,9 +119,11 @@ type ExecuteTemplate struct { ClientPrivateKeyPath string PuppetNode string PuppetServer string - ExtraArguments string PuppetBinDir string Sudo bool + WorkingDir string + Debug bool + ExtraArguments string } func (p *Provisioner) Prepare(raws ...interface{}) error { @@ -274,7 +244,6 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { ClientPrivateKeyPath: remoteClientPrivateKeyPath, PuppetNode: p.config.PuppetNode, PuppetServer: p.config.PuppetServer, - Options: p.config.Options, PuppetBinDir: p.config.PuppetBinDir, Sudo: !p.config.PreventSudo, WorkingDir: p.config.WorkingDir, From 47d46b0c6432365c8177b0471597bd2464212d66 Mon Sep 17 00:00:00 2001 From: Matthew Patton Date: Sat, 28 Apr 2018 00:17:27 -0400 Subject: [PATCH 11/21] use filpath() to make tests portable across Windows and non-Windows --- provisioner/puppet-masterless/provisioner_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/provisioner/puppet-masterless/provisioner_test.go b/provisioner/puppet-masterless/provisioner_test.go index fe64f28bd..ace41a171 100644 --- a/provisioner/puppet-masterless/provisioner_test.go +++ b/provisioner/puppet-masterless/provisioner_test.go @@ -5,6 +5,7 @@ import ( "io/ioutil" "log" "os" + "path/filepath" "strings" "testing" @@ -115,7 +116,7 @@ func TestGuestOSConfig_empty_windows(t *testing.T) { t.Fatalf("err: %s", err) } - expected := "cd C:/Windows/Temp/packer-puppet-masterless && puppet apply --detailed-exitcodes /r/m/f" + expected := "cd " + filepath.ToSlash(os.Getenv("SYSTEMROOT")) + "/Temp/packer-puppet-masterless && puppet apply --detailed-exitcodes /r/m/f" assert.Equal(t, expected, command) } @@ -150,7 +151,7 @@ func TestGuestOSConfig_full_windows(t *testing.T) { t.Fatalf("err: %s", err) } - expected := "cd C:/Windows/Temp/packer-puppet-masterless && " + + expected := "cd " + filepath.ToSlash(os.Getenv("SYSTEMROOT")) + "/Temp/packer-puppet-masterless && " + "SET \"FACTER_lhs=rhs\" & SET \"FACTER_foo=bar\" && " + "puppet apply --detailed-exitcodes --modulepath='/m/p;/a/b' --hiera_config='/h/c/p' " + "--manifestdir='/r/m/d' /r/m/f" From b4bec692ed4ee03638f7c38548e6d7ab9226129d Mon Sep 17 00:00:00 2001 From: Matthew Patton Date: Sat, 28 Apr 2018 01:13:23 -0400 Subject: [PATCH 12/21] remove accidental duplicate, initialize WorkingDir for puppet-server --- provisioner/puppet-masterless/provisioner.go | 4 ---- provisioner/puppet-server/provisioner.go | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/provisioner/puppet-masterless/provisioner.go b/provisioner/puppet-masterless/provisioner.go index 61494c9d7..6fe1d2337 100644 --- a/provisioner/puppet-masterless/provisioner.go +++ b/provisioner/puppet-masterless/provisioner.go @@ -170,10 +170,6 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { p.config.ExecuteCommand = p.guestOSTypeConfig.executeCommand } - if p.config.ExecuteCommand == "" { - p.config.ExecuteCommand = p.guestOSTypeConfig.executeCommand - } - if p.config.StagingDir == "" { p.config.StagingDir = p.guestOSTypeConfig.stagingDir } diff --git a/provisioner/puppet-server/provisioner.go b/provisioner/puppet-server/provisioner.go index 8bd29a40e..0f76c5684 100644 --- a/provisioner/puppet-server/provisioner.go +++ b/provisioner/puppet-server/provisioner.go @@ -165,6 +165,10 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { p.config.StagingDir = p.guestOSTypeConfig.stagingDir } + if p.config.WorkingDir == "" { + p.config.WorkingDir = p.config.StagingDir + } + if p.config.Facter == nil { p.config.Facter = make(map[string]string) } From f5f69df84e1e5b975ab9e1889242f72bc49d77e3 Mon Sep 17 00:00:00 2001 From: Matthew Patton Date: Mon, 30 Apr 2018 13:59:46 -0400 Subject: [PATCH 13/21] Revert "fix line-endings" This reverts commit bb1aed5264ff13ceaf029ea044f28ff2b81dce04. --- .gitattributes | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitattributes b/.gitattributes index 07e7d50e4..7230f36f4 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,2 @@ -common/test-fixtures/root/* eol=lf -*.go eol=lf +common/test-fixtures/root/* eol=lf \ No newline at end of file From 514a5978257b457f507d43e4588699b11af332aa Mon Sep 17 00:00:00 2001 From: Matthew Patton Date: Tue, 1 May 2018 16:38:01 -0400 Subject: [PATCH 14/21] alphabetize datastructures --- provisioner/puppet-masterless/provisioner.go | 36 ++++++------- provisioner/puppet-server/provisioner.go | 55 ++++++++++++-------- 2 files changed, 50 insertions(+), 41 deletions(-) diff --git a/provisioner/puppet-masterless/provisioner.go b/provisioner/puppet-masterless/provisioner.go index 6fe1d2337..56792419b 100644 --- a/provisioner/puppet-masterless/provisioner.go +++ b/provisioner/puppet-masterless/provisioner.go @@ -20,21 +20,27 @@ type Config struct { common.PackerConfig `mapstructure:",squash"` ctx interpolate.Context + // If true, staging directory is removed after executing puppet. + CleanStagingDir bool `mapstructure:"clean_staging_directory"` + + // The Guest OS Type (unix or windows) + GuestOSType string `mapstructure:"guest_os_type"` + // The command used to execute Puppet. ExecuteCommand string `mapstructure:"execute_command"` // Additional arguments to pass when executing Puppet ExtraArguments []string `mapstructure:"extra_arguments"` - // The Guest OS Type (unix or windows) - GuestOSType string `mapstructure:"guest_os_type"` - // Additional facts to set when executing Puppet Facter map[string]string // Path to a hiera configuration file to upload and use. HieraConfigPath string `mapstructure:"hiera_config_path"` + // If true, packer will ignore all exit-codes from a puppet run + IgnoreExitCodes bool `mapstructure:"ignore_exit_codes"` + // An array of local paths of modules to upload. ModulePaths []string `mapstructure:"module_paths"` @@ -48,32 +54,26 @@ type Config struct { // If true, `sudo` will NOT be used to execute Puppet. PreventSudo bool `mapstructure:"prevent_sudo"` + // The directory that contains the puppet binary. + // E.g. if it can't be found on the standard path. + PuppetBinDir string `mapstructure:"puppet_bin_dir"` + // The directory where files will be uploaded. Packer requires write // permissions in this directory. StagingDir string `mapstructure:"staging_directory"` - // If true, staging directory is removed after executing puppet. - CleanStagingDir bool `mapstructure:"clean_staging_directory"` - // The directory from which the command will be executed. // Packer requires the directory to exist when running puppet. WorkingDir string `mapstructure:"working_directory"` - - // The directory that contains the puppet binary. - // E.g. if it can't be found on the standard path. - PuppetBinDir string `mapstructure:"puppet_bin_dir"` - - // If true, packer will ignore all exit-codes from a puppet run - IgnoreExitCodes bool `mapstructure:"ignore_exit_codes"` } type guestOSTypeConfig struct { - tempDir string - stagingDir string executeCommand string facterVarsFmt string facterVarsJoiner string modulePathJoiner string + stagingDir string + tempDir string } // FIXME assumes both Packer host and target are same OS @@ -122,6 +122,8 @@ type Provisioner struct { } type ExecuteTemplate struct { + Debug bool + ExtraArguments string FacterVars string HieraConfigPath string ModulePath string @@ -130,8 +132,6 @@ type ExecuteTemplate struct { PuppetBinDir string Sudo bool WorkingDir string - Debug bool - ExtraArguments string } func (p *Provisioner) Prepare(raws ...interface{}) error { @@ -291,6 +291,7 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { } data := ExecuteTemplate{ + ExtraArguments: "", FacterVars: strings.Join(facterVars, p.guestOSTypeConfig.facterVarsJoiner), HieraConfigPath: remoteHieraConfigPath, ManifestDir: remoteManifestDir, @@ -299,7 +300,6 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { PuppetBinDir: p.config.PuppetBinDir, Sudo: !p.config.PreventSudo, WorkingDir: p.config.WorkingDir, - ExtraArguments: "", } p.config.ctx.Data = &data diff --git a/provisioner/puppet-server/provisioner.go b/provisioner/puppet-server/provisioner.go index 0f76c5684..dcb3836e9 100644 --- a/provisioner/puppet-server/provisioner.go +++ b/provisioner/puppet-server/provisioner.go @@ -19,23 +19,36 @@ type Config struct { common.PackerConfig `mapstructure:",squash"` ctx interpolate.Context + // If true, staging directory is removed after executing puppet. + CleanStagingDir bool `mapstructure:"clean_staging_directory"` + + // A path to the client certificate + ClientCertPath string `mapstructure:"client_cert_path"` + + // A path to a directory containing the client private keys + ClientPrivateKeyPath string `mapstructure:"client_private_key_path"` + // The command used to execute Puppet. ExecuteCommand string `mapstructure:"execute_command"` // Additional argument to pass when executing Puppet. ExtraArguments []string `mapstructure:"extra_arguments"` + // Additional facts to set when executing Puppet + Facter map[string]string + // The Guest OS Type (unix or windows) GuestOSType string `mapstructure:"guest_os_type"` - // Additional facts to set when executing Puppet - Facter map[string]string + // If true, packer will ignore all exit-codes from a puppet run + IgnoreExitCodes bool `mapstructure:"ignore_exit_codes"` - // A path to the client certificate - ClientCertPath string `mapstructure:"client_cert_path"` + // If true, `sudo` will NOT be used to execute Puppet. + PreventSudo bool `mapstructure:"prevent_sudo"` - // A path to a directory containing the client private keys - ClientPrivateKeyPath string `mapstructure:"client_private_key_path"` + // The directory that contains the puppet binary. + // E.g. if it can't be found on the standard path. + PuppetBinDir string `mapstructure:"puppet_bin_dir"` // The hostname of the Puppet node. PuppetNode string `mapstructure:"puppet_node"` @@ -43,9 +56,6 @@ type Config struct { // The hostname of the Puppet server. PuppetServer string `mapstructure:"puppet_server"` - // If true, `sudo` will NOT be used to execute Puppet. - PreventSudo bool `mapstructure:"prevent_sudo"` - // The directory where files will be uploaded. Packer requires write // permissions in this directory. StagingDir string `mapstructure:"staging_dir"` @@ -53,21 +63,14 @@ type Config struct { // The directory from which the command will be executed. // Packer requires the directory to exist when running puppet. WorkingDir string `mapstructure:"working_directory"` - - // The directory that contains the puppet binary. - // E.g. if it can't be found on the standard path. - PuppetBinDir string `mapstructure:"puppet_bin_dir"` - - // If true, packer will ignore all exit-codes from a puppet run - IgnoreExitCodes bool `mapstructure:"ignore_exit_codes"` } type guestOSTypeConfig struct { - tempDir string - stagingDir string executeCommand string facterVarsFmt string facterVarsJoiner string + stagingDir string + tempDir string } // FIXME assumes both Packer host and target are same OS @@ -114,16 +117,16 @@ type Provisioner struct { } type ExecuteTemplate struct { - FacterVars string ClientCertPath string ClientPrivateKeyPath string + Debug bool + ExtraArguments string + FacterVars string PuppetNode string PuppetServer string PuppetBinDir string Sudo bool WorkingDir string - Debug bool - ExtraArguments string } func (p *Provisioner) Prepare(raws ...interface{}) error { @@ -243,15 +246,15 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { } data := ExecuteTemplate{ - FacterVars: strings.Join(facterVars, p.guestOSTypeConfig.facterVarsJoiner), ClientCertPath: remoteClientCertPath, ClientPrivateKeyPath: remoteClientPrivateKeyPath, + ExtraArguments: "", + FacterVars: strings.Join(facterVars, p.guestOSTypeConfig.facterVarsJoiner), PuppetNode: p.config.PuppetNode, PuppetServer: p.config.PuppetServer, PuppetBinDir: p.config.PuppetBinDir, Sudo: !p.config.PreventSudo, WorkingDir: p.config.WorkingDir, - ExtraArguments: "", } p.config.ctx.Data = &data @@ -279,6 +282,12 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { return fmt.Errorf("Puppet exited with a non-zero exit status: %d", cmd.ExitStatus) } + if p.config.CleanStagingDir { + if err := p.removeDir(ui, comm, p.config.StagingDir); err != nil { + return fmt.Errorf("Error removing staging directory: %s", err) + } + } + return nil } From b2d78339b00ffd338547adce57150a637b9e0403 Mon Sep 17 00:00:00 2001 From: Matthew Patton Date: Tue, 1 May 2018 17:04:40 -0400 Subject: [PATCH 15/21] add missing removeDir() to allow StagingDir clean-up post-run --- provisioner/puppet-server/provisioner.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/provisioner/puppet-server/provisioner.go b/provisioner/puppet-server/provisioner.go index dcb3836e9..9535684f0 100644 --- a/provisioner/puppet-server/provisioner.go +++ b/provisioner/puppet-server/provisioner.go @@ -320,6 +320,22 @@ func (p *Provisioner) createDir(ui packer.Ui, comm packer.Communicator, dir stri return nil } +func (p *Provisioner) removeDir(ui packer.Ui, comm packer.Communicator, dir string) error { + cmd := &packer.RemoteCmd{ + Command: fmt.Sprintf("rm -fr '%s'", dir), + } + + if err := cmd.StartWithUi(comm, ui); err != nil { + return err + } + + if cmd.ExitStatus != 0 { + return fmt.Errorf("Non-zero exit status.") + } + + return nil +} + func (p *Provisioner) uploadDirectory(ui packer.Ui, comm packer.Communicator, dst string, src string) error { if err := p.createDir(ui, comm, dst); err != nil { return err From 735f5273a05a928bbae86af6ea361b85a1b919a0 Mon Sep 17 00:00:00 2001 From: Matthew Patton Date: Tue, 1 May 2018 17:16:47 -0400 Subject: [PATCH 16/21] tab/space fixup via gofmt --- provisioner/puppet-masterless/provisioner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provisioner/puppet-masterless/provisioner.go b/provisioner/puppet-masterless/provisioner.go index 56792419b..882d4fa9d 100644 --- a/provisioner/puppet-masterless/provisioner.go +++ b/provisioner/puppet-masterless/provisioner.go @@ -54,7 +54,7 @@ type Config struct { // If true, `sudo` will NOT be used to execute Puppet. PreventSudo bool `mapstructure:"prevent_sudo"` - // The directory that contains the puppet binary. + // The directory that contains the puppet binary. // E.g. if it can't be found on the standard path. PuppetBinDir string `mapstructure:"puppet_bin_dir"` From b505cecd985839ca355e60423f163250bc28ac3d Mon Sep 17 00:00:00 2001 From: Matthew Patton Date: Tue, 8 May 2018 09:53:18 -0400 Subject: [PATCH 17/21] sync docs to code --- provisioner/puppet-masterless/provisioner.go | 4 +- provisioner/puppet-server/provisioner.go | 8 +-- .../provisioners/puppet-masterless.html.md | 70 +++++++++---------- .../docs/provisioners/puppet-server.html.md | 53 +++++++++----- 4 files changed, 74 insertions(+), 61 deletions(-) diff --git a/provisioner/puppet-masterless/provisioner.go b/provisioner/puppet-masterless/provisioner.go index 882d4fa9d..c0819b89b 100644 --- a/provisioner/puppet-masterless/provisioner.go +++ b/provisioner/puppet-masterless/provisioner.go @@ -90,7 +90,7 @@ var guestOSTypeConfigs = map[string]guestOSTypeConfig{ `{{if ne .ModulePath ""}}--modulepath='{{.ModulePath}}' {{end}}` + `{{if ne .HieraConfigPath ""}}--hiera_config='{{.HieraConfigPath}}' {{end}}` + `{{if ne .ManifestDir ""}}--manifestdir='{{.ManifestDir}}' {{end}}` + - `{{if ne .ExtraArguments ""}}{{.ExtraArguments}} {{end}}` + + "{{.ExtraArguments}} " + "{{.ManifestFile}}", facterVarsFmt: "FACTER_%s='%s'", facterVarsJoiner: " ", @@ -107,7 +107,7 @@ var guestOSTypeConfigs = map[string]guestOSTypeConfig{ `{{if ne .ModulePath ""}}--modulepath='{{.ModulePath}}' {{end}}` + `{{if ne .HieraConfigPath ""}}--hiera_config='{{.HieraConfigPath}}' {{end}}` + `{{if ne .ManifestDir ""}}--manifestdir='{{.ManifestDir}}' {{end}}` + - `{{if ne .ExtraArguments ""}}{{.ExtraArguments}} {{end}}` + + "{{.ExtraArguments}} " + "{{.ManifestFile}}", facterVarsFmt: `SET "FACTER_%s=%s"`, facterVarsJoiner: " & ", diff --git a/provisioner/puppet-server/provisioner.go b/provisioner/puppet-server/provisioner.go index 9535684f0..2118bd60e 100644 --- a/provisioner/puppet-server/provisioner.go +++ b/provisioner/puppet-server/provisioner.go @@ -85,10 +85,10 @@ var guestOSTypeConfigs = map[string]guestOSTypeConfig{ "puppet agent --onetime --no-daemonize --detailed-exitcodes " + "{{if .Debug}}--debug {{end}}" + `{{if ne .PuppetServer ""}}--server='{{.PuppetServer}}' {{end}}` + - `{{if ne .PuppetNode ""}}--certname={{.PuppetNode}} {{end}}` + + `{{if ne .PuppetNode ""}}--certname='{{.PuppetNode}}' {{end}}` + `{{if ne .ClientCertPath ""}}--certdir='{{.ClientCertPath}}' {{end}}` + `{{if ne .ClientPrivateKeyPath ""}}--privatekeydir='{{.ClientPrivateKeyPath}}' {{end}}` + - `{{if ne .ExtraArguments ""}}{{.ExtraArguments}} {{end}}`, + "{{.ExtraArguments}} ", facterVarsFmt: "FACTER_%s='%s'", facterVarsJoiner: " ", }, @@ -101,10 +101,10 @@ var guestOSTypeConfigs = map[string]guestOSTypeConfig{ "puppet agent --onetime --no-daemonize --detailed-exitcodes " + "{{if .Debug}}--debug {{end}}" + `{{if ne .PuppetServer ""}}--server='{{.PuppetServer}}' {{end}}` + - `{{if ne .PuppetNode ""}}--certname={{.PuppetNode}} {{end}}` + + `{{if ne .PuppetNode ""}}--certname='{{.PuppetNode}}' {{end}}` + `{{if ne .ClientCertPath ""}}--certdir='{{.ClientCertPath}}' {{end}}` + `{{if ne .ClientPrivateKeyPath ""}}--privatekeydir='{{.ClientPrivateKeyPath}}' {{end}}` + - `{{if ne .ExtraArguments ""}}{{.ExtraArguments}} {{end}}`, + "{{.ExtraArguments}} ", facterVarsFmt: `SET "FACTER_%s=%s"`, facterVarsJoiner: " & ", }, diff --git a/website/source/docs/provisioners/puppet-masterless.html.md b/website/source/docs/provisioners/puppet-masterless.html.md index 1e1689d03..448a2e880 100644 --- a/website/source/docs/provisioners/puppet-masterless.html.md +++ b/website/source/docs/provisioners/puppet-masterless.html.md @@ -59,11 +59,19 @@ Optional parameters: variables](/docs/templates/engine.html) available. See below for more information. -- `extra_arguments` (array of strings) - This is an array of additional options to - pass to the puppet command when executing puppet. This allows for - customization of the `execute_command` without having to completely replace - or include it's contents, making forward-compatible customizations much - easier. +- `extra_arguments` (array of strings) - Additional options to + pass to the Puppet command. This allows for customization of the + `execute_command` without having to completely replace + or subsume its contents, making forward-compatible customizations much + easier to maintain. + + This string is lazy-evaluated so one can incorporate logic driven by other parameters. +``` +[ + {{if ne "{{user environment}}" ""}}--environment={{user environment}}{{end}}, + {{if ne ".ModulePath" ""}}--modulepath='{{.ModulePath}}:$({{.PuppetBinDir}}/puppet config print {{if ne "{{user `environment`}}" ""}}--environment={{user `environment`}}{{end}} modulepath)'{{end}} +] +``` - `facter` (object of key/value strings) - Additional [facts](https://puppetlabs.com/facter) to make @@ -71,7 +79,7 @@ Optional parameters: - `guest_os_type` (string) - The target guest OS type, either "unix" or "windows". Setting this to "windows" will cause the provisioner to use - Windows friendly paths and commands. By default, this is "unix". + Windows friendly paths and commands. By default, this is "unix". - `hiera_config_path` (string) - The path to a local file with hiera configuration to be uploaded to the remote machine. Hiera data directories @@ -124,45 +132,33 @@ readability) to execute Puppet: ``` cd {{.WorkingDir}} && - {{if ne .FacterVars ""}}{{.FacterVars}} {{end}} -{{if .Sudo}}sudo -E {{end}} -{{if ne .PuppetBinDir ""}}{{.PuppetBinDir}}/{{end}} -puppet apply --verbose --modulepath='{{.ModulePath}}' - {{if ne .HieraConfigPath ""}}--hiera_config='{{.HieraConfigPath}}' {{end}} -{{if ne .ManifestDir ""}}--manifestdir='{{.ManifestDir}}' {{end}} ---detailed-exitcodes - {{if ne .ExtraArguments ""}}{{.ExtraArguments}} {{end}} -{{.ManifestFile}} + {{if ne .FacterVars ""}}{{.FacterVars}} {{end}} + {{if .Sudo}}sudo -E {{end}} + {{if ne .PuppetBinDir ""}}{{.PuppetBinDir}}/{{end}} + puppet apply --detailed-exitcodes + {{if .Debug}}--debug {{end}} + {{if ne .ModulePath ""}}--modulepath='{{.ModulePath}}' {{end}} + {{if ne .HieraConfigPath ""}}--hiera_config='{{.HieraConfigPath}}' {{end}} + {{if ne .ManifestDir ""}}--manifestdir='{{.ManifestDir}}' {{end}} + {{.ExtraArguments}} + {{.ManifestFile}} ``` The following command is used if guest OS type is windows: ``` cd {{.WorkingDir}} && - {{.FacterVars}} && - {{if ne .PuppetBinDir ""}}{{.PuppetBinDir}}/{{end}} -puppet apply --verbose --modulepath='{{.ModulePath}}' - {{if ne .HieraConfigPath ""}}--hiera_config='{{.HieraConfigPath}}' {{end}} -{{if ne .ManifestDir ""}}--manifestdir='{{.ManifestDir}}' {{end}} ---detailed-exitcodes - {{if ne .ExtraArguments ""}}{{.ExtraArguments}} {{end}} -{{.ManifestFile}} + {{if ne .FacterVars ""}}{{.FacterVars}} && {{end}} + {{if ne .PuppetBinDir ""}}{{.PuppetBinDir}}/{{end}} + puppet apply --detailed-exitcodes + {{if .Debug}}--debug {{end}} + {{if ne .ModulePath ""}}--modulepath='{{.ModulePath}}' {{end}} + {{if ne .HieraConfigPath ""}}--hiera_config='{{.HieraConfigPath}}' {{end}} + {{if ne .ManifestDir ""}}--manifestdir='{{.ManifestDir}}' {{end}} + {{.ExtraArguments}} + {{.ManifestFile}} ``` -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: - -- `WorkingDir` - The path from which Puppet will be executed. -- `FacterVars` - Shell-friendly string of environmental variables used to set - custom facts configured for this provisioner. -- `HieraConfigPath` - The path to a hiera configuration file. -- `ManifestFile` - The path on the remote machine to the manifest file for - Puppet to use. -- `ModulePath` - The paths to the module directories. -- `Sudo` - A boolean of whether to `sudo` the command or not, depending on the - value of the `prevent_sudo` configuration. - ## Default Facts In addition to being able to specify custom Facter facts using the `facter` diff --git a/website/source/docs/provisioners/puppet-server.html.md b/website/source/docs/provisioners/puppet-server.html.md index 180f52b02..af09b9ace 100644 --- a/website/source/docs/provisioners/puppet-server.html.md +++ b/website/source/docs/provisioners/puppet-server.html.md @@ -54,6 +54,20 @@ listed below: various [configuration template variables](/docs/templates/engine.html) available. See below for more information. +- `extra_arguments` (array of strings) - Additional options to + pass to the puppet command. This allows for customization of the + `execute_command` without having to completely replace + or subsume its contents, making forward-compatible customizations much + easier to maintain. + + This string is lazy-evaluated so one can incorporate logic driven by other parameters. +``` +[ + {{if ne "{{user environment}}" ""}}--environment={{user environment}}{{end}} + {{if ne ".ModulePath" ""}}--modulepath='{{.ModulePath}}:$({{.PuppetBinDir}}/puppet config print {{if ne "{{user `environment`}}" ""}}--environment={{user `environment`}}{{end}} modulepath)'{{end}} +] +``` + - `facter` (object of key/value strings) - Additional Facter facts to make available to the Puppet run. @@ -95,29 +109,32 @@ By default, Packer uses the following command (broken across multiple lines for readability) to execute Puppet: ``` -{{.FacterVars}} {{if .Sudo}}sudo -E {{end}} -{{if ne .PuppetBinDir ""}}{{.PuppetBinDir}}/{{end}}puppet agent ---onetime --no-daemonize -{{if ne .PuppetServer ""}}--server='{{.PuppetServer}}' {{end}} -{{if ne .Options ""}}{{.Options}} {{end}} -{{if ne .PuppetNode ""}}--certname={{.PuppetNode}} {{end}} -{{if ne .ClientCertPath ""}}--certdir='{{.ClientCertPath}}' {{end}} -{{if ne .ClientPrivateKeyPath ""}}--privatekeydir='{{.ClientPrivateKeyPath}}' {{end}} ---detailed-exitcodes +cd {{.WorkingDir}} && + {{if ne .FacterVars ""}}{{.FacterVars}} {{end}} + {{if .Sudo}}sudo -E {{end}} + {{if ne .PuppetBinDir ""}}{{.PuppetBinDir}}/{{end}} + puppet agent --onetime --no-daemonize --detailed-exitcodes + {{if .Debug}}--debug {{end}} + {{if ne .PuppetServer ""}}--server='{{.PuppetServer}}' {{end}} + {{if ne .PuppetNode ""}}--certname='{{.PuppetNode}}' {{end}} + {{if ne .ClientCertPath ""}}--certdir='{{.ClientCertPath}}' {{end}} + {{if ne .ClientPrivateKeyPath ""}}--privatekeydir='{{.ClientPrivateKeyPath}}' {{end}} + "{{.ExtraArguments}} " ``` The following command is used if guest OS type is windows: ``` -{{.FacterVars}} -{{if ne .PuppetBinDir ""}}{{.PuppetBinDir}}/{{end}}puppet agent ---onetime --no-daemonize -{{if ne .PuppetServer ""}}--server='{{.PuppetServer}}' {{end}} -{{if ne .Options ""}}{{.Options}} {{end}} -{{if ne .PuppetNode ""}}--certname={{.PuppetNode}} {{end}} -{{if ne .ClientCertPath ""}}--certdir='{{.ClientCertPath}}' {{end}} -{{if ne .ClientPrivateKeyPath ""}}--privatekeydir='{{.ClientPrivateKeyPath}}' {{end}} ---detailed-exitcodes +cd {{.WorkingDir}} && + {{if ne .FacterVars ""}}{{.FacterVars}} && {{end}} + {{if ne .PuppetBinDir ""}}{{.PuppetBinDir}}/{{end}} + puppet agent --onetime --no-daemonize --detailed-exitcodes + {{if .Debug}}--debug {{end}} + {{if ne .PuppetServer ""}}--server='{{.PuppetServer}}' {{end}} + {{if ne .PuppetNode ""}}--certname='{{.PuppetNode}}' {{end}} + {{if ne .ClientCertPath ""}}--certdir='{{.ClientCertPath}}' {{end}} + {{if ne .ClientPrivateKeyPath ""}}--privatekeydir='{{.ClientPrivateKeyPath}}' {{end}} + "{{.ExtraArguments}} " ``` ## Default Facts From 399edbe5e7c5dc03d274558a7ab1f2189dddea0e Mon Sep 17 00:00:00 2001 From: Matthew Patton Date: Tue, 8 May 2018 10:12:22 -0400 Subject: [PATCH 18/21] revert false economy WRT .ExtraArguments --- provisioner/puppet-masterless/provisioner.go | 4 ++-- provisioner/puppet-server/provisioner.go | 4 ++-- website/source/docs/provisioners/puppet-masterless.html.md | 4 ++-- website/source/docs/provisioners/puppet-server.html.md | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/provisioner/puppet-masterless/provisioner.go b/provisioner/puppet-masterless/provisioner.go index c0819b89b..882d4fa9d 100644 --- a/provisioner/puppet-masterless/provisioner.go +++ b/provisioner/puppet-masterless/provisioner.go @@ -90,7 +90,7 @@ var guestOSTypeConfigs = map[string]guestOSTypeConfig{ `{{if ne .ModulePath ""}}--modulepath='{{.ModulePath}}' {{end}}` + `{{if ne .HieraConfigPath ""}}--hiera_config='{{.HieraConfigPath}}' {{end}}` + `{{if ne .ManifestDir ""}}--manifestdir='{{.ManifestDir}}' {{end}}` + - "{{.ExtraArguments}} " + + `{{if ne .ExtraArguments ""}}{{.ExtraArguments}} {{end}}` + "{{.ManifestFile}}", facterVarsFmt: "FACTER_%s='%s'", facterVarsJoiner: " ", @@ -107,7 +107,7 @@ var guestOSTypeConfigs = map[string]guestOSTypeConfig{ `{{if ne .ModulePath ""}}--modulepath='{{.ModulePath}}' {{end}}` + `{{if ne .HieraConfigPath ""}}--hiera_config='{{.HieraConfigPath}}' {{end}}` + `{{if ne .ManifestDir ""}}--manifestdir='{{.ManifestDir}}' {{end}}` + - "{{.ExtraArguments}} " + + `{{if ne .ExtraArguments ""}}{{.ExtraArguments}} {{end}}` + "{{.ManifestFile}}", facterVarsFmt: `SET "FACTER_%s=%s"`, facterVarsJoiner: " & ", diff --git a/provisioner/puppet-server/provisioner.go b/provisioner/puppet-server/provisioner.go index 2118bd60e..b7ec34ea7 100644 --- a/provisioner/puppet-server/provisioner.go +++ b/provisioner/puppet-server/provisioner.go @@ -88,7 +88,7 @@ var guestOSTypeConfigs = map[string]guestOSTypeConfig{ `{{if ne .PuppetNode ""}}--certname='{{.PuppetNode}}' {{end}}` + `{{if ne .ClientCertPath ""}}--certdir='{{.ClientCertPath}}' {{end}}` + `{{if ne .ClientPrivateKeyPath ""}}--privatekeydir='{{.ClientPrivateKeyPath}}' {{end}}` + - "{{.ExtraArguments}} ", + `{{if ne .ExtraArguments ""}}{{.ExtraArguments}} {{end}}`, facterVarsFmt: "FACTER_%s='%s'", facterVarsJoiner: " ", }, @@ -104,7 +104,7 @@ var guestOSTypeConfigs = map[string]guestOSTypeConfig{ `{{if ne .PuppetNode ""}}--certname='{{.PuppetNode}}' {{end}}` + `{{if ne .ClientCertPath ""}}--certdir='{{.ClientCertPath}}' {{end}}` + `{{if ne .ClientPrivateKeyPath ""}}--privatekeydir='{{.ClientPrivateKeyPath}}' {{end}}` + - "{{.ExtraArguments}} ", + `{{if ne .ExtraArguments ""}}{{.ExtraArguments}} {{end}}`, facterVarsFmt: `SET "FACTER_%s=%s"`, facterVarsJoiner: " & ", }, diff --git a/website/source/docs/provisioners/puppet-masterless.html.md b/website/source/docs/provisioners/puppet-masterless.html.md index 448a2e880..341bf3867 100644 --- a/website/source/docs/provisioners/puppet-masterless.html.md +++ b/website/source/docs/provisioners/puppet-masterless.html.md @@ -140,7 +140,7 @@ cd {{.WorkingDir}} && {{if ne .ModulePath ""}}--modulepath='{{.ModulePath}}' {{end}} {{if ne .HieraConfigPath ""}}--hiera_config='{{.HieraConfigPath}}' {{end}} {{if ne .ManifestDir ""}}--manifestdir='{{.ManifestDir}}' {{end}} - {{.ExtraArguments}} + {{if ne .ExtraArguments ""}}{{.ExtraArguments}} {{end}} {{.ManifestFile}} ``` @@ -155,7 +155,7 @@ cd {{.WorkingDir}} && {{if ne .ModulePath ""}}--modulepath='{{.ModulePath}}' {{end}} {{if ne .HieraConfigPath ""}}--hiera_config='{{.HieraConfigPath}}' {{end}} {{if ne .ManifestDir ""}}--manifestdir='{{.ManifestDir}}' {{end}} - {{.ExtraArguments}} + {{if ne .ExtraArguments ""}}{{.ExtraArguments}} {{end}} {{.ManifestFile}} ``` diff --git a/website/source/docs/provisioners/puppet-server.html.md b/website/source/docs/provisioners/puppet-server.html.md index af09b9ace..98043675d 100644 --- a/website/source/docs/provisioners/puppet-server.html.md +++ b/website/source/docs/provisioners/puppet-server.html.md @@ -119,7 +119,7 @@ cd {{.WorkingDir}} && {{if ne .PuppetNode ""}}--certname='{{.PuppetNode}}' {{end}} {{if ne .ClientCertPath ""}}--certdir='{{.ClientCertPath}}' {{end}} {{if ne .ClientPrivateKeyPath ""}}--privatekeydir='{{.ClientPrivateKeyPath}}' {{end}} - "{{.ExtraArguments}} " + {{if ne .ExtraArguments ""}}{{.ExtraArguments}} {{end}} ``` The following command is used if guest OS type is windows: @@ -134,7 +134,7 @@ cd {{.WorkingDir}} && {{if ne .PuppetNode ""}}--certname='{{.PuppetNode}}' {{end}} {{if ne .ClientCertPath ""}}--certdir='{{.ClientCertPath}}' {{end}} {{if ne .ClientPrivateKeyPath ""}}--privatekeydir='{{.ClientPrivateKeyPath}}' {{end}} - "{{.ExtraArguments}} " + {{if ne .ExtraArguments ""}}{{.ExtraArguments}} {{end}} ``` ## Default Facts From 5c7d5fac75db07f67bb5946748c3eed76c9d4399 Mon Sep 17 00:00:00 2001 From: Matthew Patton Date: Tue, 8 May 2018 12:21:04 -0400 Subject: [PATCH 19/21] expose OS-specific ModulePathJoiner --- provisioner/puppet-masterless/provisioner.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/provisioner/puppet-masterless/provisioner.go b/provisioner/puppet-masterless/provisioner.go index 882d4fa9d..35a565d1e 100644 --- a/provisioner/puppet-masterless/provisioner.go +++ b/provisioner/puppet-masterless/provisioner.go @@ -127,6 +127,7 @@ type ExecuteTemplate struct { FacterVars string HieraConfigPath string ModulePath string + ModulePathJoiner string ManifestFile string ManifestDir string PuppetBinDir string @@ -297,6 +298,7 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { ManifestDir: remoteManifestDir, ManifestFile: remoteManifestFile, ModulePath: strings.Join(modulePaths, p.guestOSTypeConfig.modulePathJoiner), + ModulePathJoiner: p.guestOSTypeConfig.modulePathJoiner, PuppetBinDir: p.config.PuppetBinDir, Sudo: !p.config.PreventSudo, WorkingDir: p.config.WorkingDir, From f510a8667bacbcb2f52eb278b75c0d2796cb4772 Mon Sep 17 00:00:00 2001 From: Matthew Patton Date: Tue, 8 May 2018 12:29:13 -0400 Subject: [PATCH 20/21] standardize documentation between provisioners. --- .../provisioners/puppet-masterless.html.md | 86 ++++++++----------- .../docs/provisioners/puppet-server.html.md | 52 ++++++----- 2 files changed, 61 insertions(+), 77 deletions(-) diff --git a/website/source/docs/provisioners/puppet-masterless.html.md b/website/source/docs/provisioners/puppet-masterless.html.md index 341bf3867..9afb2f759 100644 --- a/website/source/docs/provisioners/puppet-masterless.html.md +++ b/website/source/docs/provisioners/puppet-masterless.html.md @@ -54,76 +54,64 @@ Required parameters: Optional parameters: -- `execute_command` (string) - The command used to execute Puppet. This has - various [configuration template - variables](/docs/templates/engine.html) available. See - below for more information. +- `execute_command` (string) - The command-line to execute Puppet. This also has + various [configuration template variables](/docs/templates/engine.html) available. - `extra_arguments` (array of strings) - Additional options to - pass to the Puppet command. This allows for customization of the + pass to the Puppet command. This allows for customization of `execute_command` without having to completely replace or subsume its contents, making forward-compatible customizations much easier to maintain. - This string is lazy-evaluated so one can incorporate logic driven by other parameters. + This string is lazy-evaluated so one can incorporate logic driven by template variables as + well as private elements of ExecuteTemplate (see source: provisioner/puppet-masterless/provisioner.go). ``` [ {{if ne "{{user environment}}" ""}}--environment={{user environment}}{{end}}, - {{if ne ".ModulePath" ""}}--modulepath='{{.ModulePath}}:$({{.PuppetBinDir}}/puppet config print {{if ne "{{user `environment`}}" ""}}--environment={{user `environment`}}{{end}} modulepath)'{{end}} + {{if ne ".ModulePath" ""}}--modulepath="{{.ModulePath}}{{.ModulePathJoiner}}$(puppet config print {{if ne "{{user `environment`}}" ""}}--environment={{user `environment`}}{{end}} modulepath)"{{end}} ] ``` -- `facter` (object of key/value strings) - Additional +- `facter` (object of key:value strings) - Additional [facts](https://puppetlabs.com/facter) to make - available when Puppet is running. + available to the Puppet run. -- `guest_os_type` (string) - The target guest OS type, either "unix" or - "windows". Setting this to "windows" will cause the provisioner to use - Windows friendly paths and commands. By default, this is "unix". +- `guest_os_type` (string) - The remote host's OS type ('windows' or 'unix') to + tailor command-line and path separators. (default: unix). -- `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. +- `hiera_config_path` (string) - Local path to self-contained Hiera + data to be uploaded. NOTE: If you need data directories + they must be previously transferred with a File provisioner. -- `ignore_exit_codes` (boolean) - If true, Packer will never consider the - provisioner a failure. +- `ignore_exit_codes` (boolean) - If true, Packer will ignore failures. -- `manifest_dir` (string) - The path to a local directory with manifests to be - uploaded to the remote machine. This is useful if your main manifest file - uses imports. This directory doesn't necessarily contain the - `manifest_file`. It is a separate directory that will be set as the - "manifestdir" setting on Puppet. +- `manifest_dir` (string) - Local directory with manifests to be + uploaded. This is useful if your main manifest uses imports, but the + directory might not contain the `manifest_file` itself. -~> `manifest_dir` is passed to `puppet apply` as the `--manifestdir` option. +~> `manifest_dir` is passed to Puppet as `--manifestdir` option. This option was deprecated in puppet 3.6, and removed in puppet 4.0. If you have multiple manifests you should use `manifest_file` instead. -- `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. - -- `prevent_sudo` (boolean) - By default, the configured commands that are - executed to run Puppet are executed with `sudo`. If this is true, then the - sudo will be omitted. - -- `puppet_bin_dir` (string) - The path to the directory that contains the puppet - binary for running `puppet apply`. Usually, this would be found via the `$PATH` - or `%PATH%` environment variable, but some builders (notably, the Docker one) do - not run profile-setup scripts, therefore the path is usually empty. - -- `staging_directory` (string) - This is the directory where all the configuration - of Puppet by Packer will be placed. By default this is "/tmp/packer-puppet-masterless" - when guest OS type is unix and "C:/Windows/Temp/packer-puppet-masterless" when windows. - This directory doesn't need to exist but must have proper permissions so that the SSH - user that Packer uses is able to create directories and write into this folder. - If the permissions are not correct, use a shell provisioner prior to this to configure - it properly. - -- `working_directory` (string) - This is the directory from which the puppet - command will be run. When using hiera with a relative path, this option - allows to ensure that the paths are working properly. If not specified, - defaults to the value of specified `staging_directory` (or its default value - if not specified either). +- `module_paths` (array of strings) - Array of local module + directories to be uploaded. + +- `prevent_sudo` (boolean) - On Unix platforms Puppet is typically invoked with `sudo`. If true, + it will be omitted. (default: false) + +- `puppet_bin_dir` (string) - Path to the Puppet binary. Ideally the program + should be on the system (unix: `$PATH`, windows: `%PATH%`), but some builders (eg. Docker) do + not run profile-setup scripts and therefore PATH might be empty or minimal. + +- `staging_directory` (string) - Directory to where uploaded files + will be placed (unix: "/tmp/packer-puppet-masterless", + windows: "%SYSTEMROOT%/Temp/packer-puppet-masterless"). + It doesn't need to pre-exist, but the parent must have permissions sufficient + for the account Packer connects as to create directories and write files. + Use a Shell provisioner to prepare the way if needed. + +- `working_directory` (string) - Directory from which `execute_command` will be run. + If using Hiera files with relative paths, this option can be helpful. (default: `staging_directory`) ## Execute Command diff --git a/website/source/docs/provisioners/puppet-server.html.md b/website/source/docs/provisioners/puppet-server.html.md index 98043675d..b8528822a 100644 --- a/website/source/docs/provisioners/puppet-server.html.md +++ b/website/source/docs/provisioners/puppet-server.html.md @@ -50,45 +50,38 @@ listed below: contains the client private key for the node. This defaults to nothing, in which case a client private key won't be uploaded. -- `execute_command` (string) - The command used to execute Puppet. This has +- `execute_command` (string) - The command-line to execute Puppet. This also has various [configuration template variables](/docs/templates/engine.html) available. - See below for more information. - `extra_arguments` (array of strings) - Additional options to - pass to the puppet command. This allows for customization of the + pass to the Puppet command. This allows for customization of `execute_command` without having to completely replace or subsume its contents, making forward-compatible customizations much easier to maintain. - This string is lazy-evaluated so one can incorporate logic driven by other parameters. + This string is lazy-evaluated so one can incorporate logic driven by template variables as + well as private elements of ExecuteTemplate (see source: provisioner/puppet-server/provisioner.go). ``` [ {{if ne "{{user environment}}" ""}}--environment={{user environment}}{{end}} - {{if ne ".ModulePath" ""}}--modulepath='{{.ModulePath}}:$({{.PuppetBinDir}}/puppet config print {{if ne "{{user `environment`}}" ""}}--environment={{user `environment`}}{{end}} modulepath)'{{end}} ] ``` -- `facter` (object of key/value strings) - Additional Facter facts to make +- `facter` (object of key/value strings) - Additional + [facts](https://puppetlabs.com/facter) to make available to the Puppet run. -- `guest_os_type` (string) - The target guest OS type, either "unix" or - "windows". Setting this to "windows" will cause the provisioner to use - Windows friendly paths and commands. By default, this is "unix". +- `guest_os_type` (string) - The remote host's OS type ('windows' or 'unix') to + tailor command-line and path separators. (default: unix). -- `ignore_exit_codes` (boolean) - If true, Packer will never consider the - provisioner a failure. +- `ignore_exit_codes` (boolean) - If true, Packer will ignore failures. -- `options` (string) - Additional command line options to pass to - `puppet agent` when Puppet is run. +- `prevent_sudo` (boolean) - On Unix platforms Puppet is typically invoked with `sudo`. If true, + it will be omitted. (default: false) -- `prevent_sudo` (boolean) - By default, the configured commands that are - executed to run Puppet are executed with `sudo`. If this is true, then the - sudo will be omitted. - -- `puppet_bin_dir` (string) - The path to the directory that contains the puppet - binary for running `puppet agent`. Usually, this would be found via the `$PATH` - or `%PATH%` environment variable, but some builders (notably, the Docker one) do - not run profile-setup scripts, therefore the path is usually empty. +- `puppet_bin_dir` (string) - Path to the Puppet binary. Ideally the program + should be on the system (unix: `$PATH`, windows: `%PATH%`), but some builders (eg. Docker) do + not run profile-setup scripts and therefore PATH might be empty or minimal. - `puppet_node` (string) - The name of the node. If this isn't set, the fully qualified domain name will be used. @@ -96,14 +89,17 @@ listed below: - `puppet_server` (string) - Hostname of the Puppet server. By default "puppet" will be used. -- `staging_dir` (string) - This is the directory where all the - configuration of Puppet by Packer will be placed. By default this - is /tmp/packer-puppet-server. This directory doesn't need to exist but - must have proper permissions so that the SSH user that Packer uses is able - to create directories and write into this folder. If the permissions are not - correct, use a shell provisioner prior to this to configure it properly. +- `staging_dir` (string) - Directory to where uploaded files + will be placed (unix: "/tmp/packer-puppet-masterless", + windows: "%SYSTEMROOT%/Temp/packer-puppet-masterless"). + It doesn't need to pre-exist, but the parent must have permissions sufficient + for the account Packer connects as to create directories and write files. + Use a Shell provisioner to prepare the way if needed. + +- `working_directory` (string) - Directory from which `execute_command` will be run. + If using Hiera files with relative paths, this option can be helpful. (default: `staging_directory`) -## Execute Command + ## Execute Command By default, Packer uses the following command (broken across multiple lines for readability) to execute Puppet: From d22fb6d60ba4c61c3c27ca46afd430e892501cb1 Mon Sep 17 00:00:00 2001 From: Matthew Patton Date: Tue, 8 May 2018 12:44:15 -0400 Subject: [PATCH 21/21] reformat via gofmt --- provisioner/puppet-masterless/provisioner.go | 38 ++++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/provisioner/puppet-masterless/provisioner.go b/provisioner/puppet-masterless/provisioner.go index 35a565d1e..3254a6134 100644 --- a/provisioner/puppet-masterless/provisioner.go +++ b/provisioner/puppet-masterless/provisioner.go @@ -122,17 +122,17 @@ type Provisioner struct { } type ExecuteTemplate struct { - Debug bool - ExtraArguments string - FacterVars string - HieraConfigPath string - ModulePath string + Debug bool + ExtraArguments string + FacterVars string + HieraConfigPath string + ModulePath string ModulePathJoiner string - ManifestFile string - ManifestDir string - PuppetBinDir string - Sudo bool - WorkingDir string + ManifestFile string + ManifestDir string + PuppetBinDir string + Sudo bool + WorkingDir string } func (p *Provisioner) Prepare(raws ...interface{}) error { @@ -292,16 +292,16 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { } data := ExecuteTemplate{ - ExtraArguments: "", - FacterVars: strings.Join(facterVars, p.guestOSTypeConfig.facterVarsJoiner), - HieraConfigPath: remoteHieraConfigPath, - ManifestDir: remoteManifestDir, - ManifestFile: remoteManifestFile, - ModulePath: strings.Join(modulePaths, p.guestOSTypeConfig.modulePathJoiner), + ExtraArguments: "", + FacterVars: strings.Join(facterVars, p.guestOSTypeConfig.facterVarsJoiner), + HieraConfigPath: remoteHieraConfigPath, + ManifestDir: remoteManifestDir, + ManifestFile: remoteManifestFile, + ModulePath: strings.Join(modulePaths, p.guestOSTypeConfig.modulePathJoiner), ModulePathJoiner: p.guestOSTypeConfig.modulePathJoiner, - PuppetBinDir: p.config.PuppetBinDir, - Sudo: !p.config.PreventSudo, - WorkingDir: p.config.WorkingDir, + PuppetBinDir: p.config.PuppetBinDir, + Sudo: !p.config.PreventSudo, + WorkingDir: p.config.WorkingDir, } p.config.ctx.Data = &data