Update puppet-masterless commands to be OS specific
Previous implementation hardcoded "mkdir -p" which is fine for Unix, but fails on Windows. This change draws on the example in the chef-solo provisioner on how to detect the OS in use and use an appropriate mkdir command. In addition to updating the mkdir command, the actual executeCommand needs to be OS specific, since Windows doesn't have sudo and Unix doesn't require 'SET' when trying to change the value of a variable. Modify the actual Windows command used to run Puppet. Since the Facter vars on Windows are set with 'SET <varname>=<value>', a '&&' is needed between the SET commands and the actual Puppet invocation.
This commit is contained in:
parent
1c592f291e
commit
bcd30ad2f2
|
@ -9,10 +9,11 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/helper/config"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/hashicorp/packer/template/interpolate"
|
||||
"github.com/mitchellh/packer/common"
|
||||
"github.com/mitchellh/packer/helper/config"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"github.com/mitchellh/packer/provisioner"
|
||||
"github.com/mitchellh/packer/template/interpolate"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
|
@ -61,10 +62,45 @@ type Config struct {
|
|||
|
||||
// If true, packer will ignore all exit-codes from a puppet run
|
||||
IgnoreExitCodes bool `mapstructure:"ignore_exit_codes"`
|
||||
|
||||
GuestOSType string `mapstructure:"guest_os_type"`
|
||||
ConfigTemplate string `mapstructure:"config_template"`
|
||||
}
|
||||
|
||||
type guestOSTypeConfig struct {
|
||||
stagingDir string
|
||||
executeCommand string
|
||||
}
|
||||
|
||||
var guestOSTypeConfigs = map[string]guestOSTypeConfig{
|
||||
provisioner.UnixOSType: guestOSTypeConfig{
|
||||
stagingDir: "/tmp/packer-puppet-masterless",
|
||||
executeCommand: "cd {{.WorkingDir}} && " +
|
||||
"{{.FacterVars}} {{if .Sudo}} sudo -E {{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}}",
|
||||
},
|
||||
provisioner.WindowsOSType: guestOSTypeConfig{
|
||||
stagingDir: "C:/Windows/Temp/packer-puppet-masterless",
|
||||
executeCommand: "cd {{.WorkingDir}} && " +
|
||||
"{{.FacterVars}} && " +
|
||||
"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}}",
|
||||
},
|
||||
}
|
||||
|
||||
type Provisioner struct {
|
||||
config Config
|
||||
config Config
|
||||
guestOSTypeConfig guestOSTypeConfig
|
||||
guestCommands *provisioner.GuestCommands
|
||||
}
|
||||
|
||||
type ExecuteTemplate struct {
|
||||
|
@ -95,15 +131,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
|
|||
|
||||
// Set some defaults
|
||||
if p.config.ExecuteCommand == "" {
|
||||
p.config.ExecuteCommand = "cd {{.WorkingDir}} && " +
|
||||
"{{.FacterVars}} {{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}}"
|
||||
p.config.ExecuteCommand = p.guestOSTypeConfig.executeCommand
|
||||
}
|
||||
|
||||
if p.config.StagingDir == "" {
|
||||
|
@ -166,6 +194,37 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
|
|||
}
|
||||
}
|
||||
|
||||
if p.config.GuestOSType == "" {
|
||||
p.config.GuestOSType = provisioner.DefaultOSType
|
||||
}
|
||||
p.config.GuestOSType = strings.ToLower(p.config.GuestOSType)
|
||||
|
||||
var ok bool
|
||||
p.guestOSTypeConfig, ok = guestOSTypeConfigs[p.config.GuestOSType]
|
||||
if !ok {
|
||||
return fmt.Errorf("Invalid guest_os_type: \"%s\"", p.config.GuestOSType)
|
||||
}
|
||||
|
||||
p.guestCommands, err = provisioner.NewGuestCommands(p.config.GuestOSType, !p.config.PreventSudo)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Invalid guest_os_type: \"%s\"", p.config.GuestOSType)
|
||||
}
|
||||
|
||||
if p.config.ExecuteCommand == "" {
|
||||
p.config.ExecuteCommand = p.guestOSTypeConfig.executeCommand
|
||||
}
|
||||
|
||||
if p.config.ConfigTemplate != "" {
|
||||
fi, err := os.Stat(p.config.ConfigTemplate)
|
||||
if err != nil {
|
||||
errs = packer.MultiErrorAppend(
|
||||
errs, fmt.Errorf("Bad config template path: %s", err))
|
||||
} else if fi.IsDir() {
|
||||
errs = packer.MultiErrorAppend(
|
||||
errs, fmt.Errorf("Config template path must be a file: %s", err))
|
||||
}
|
||||
}
|
||||
|
||||
if errs != nil && len(errs.Errors) > 0 {
|
||||
return errs
|
||||
}
|
||||
|
@ -227,8 +286,15 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
|
|||
}
|
||||
|
||||
// Execute Puppet
|
||||
var facterVarsString string
|
||||
if p.config.GuestOSType == provisioner.UnixOSType {
|
||||
facterVarsString = strings.Join(facterVars, " ")
|
||||
} else {
|
||||
facterVarsString = "SET " + strings.Join(facterVars, " && SET ")
|
||||
}
|
||||
|
||||
p.config.ctx.Data = &ExecuteTemplate{
|
||||
FacterVars: strings.Join(facterVars, " "),
|
||||
FacterVars: facterVarsString,
|
||||
HieraConfigPath: remoteHieraConfigPath,
|
||||
ManifestDir: remoteManifestDir,
|
||||
ManifestFile: remoteManifestFile,
|
||||
|
@ -249,7 +315,7 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
|
|||
|
||||
ui.Message(fmt.Sprintf("Running Puppet: %s", command))
|
||||
if err := cmd.StartWithUi(comm, ui); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("Got an error starting command: %s", err)
|
||||
}
|
||||
|
||||
if cmd.ExitStatus != 0 && cmd.ExitStatus != 2 && !p.config.IgnoreExitCodes {
|
||||
|
@ -335,9 +401,9 @@ func (p *Provisioner) uploadManifests(ui packer.Ui, comm packer.Communicator) (s
|
|||
}
|
||||
|
||||
func (p *Provisioner) createDir(ui packer.Ui, comm packer.Communicator, dir string) error {
|
||||
cmd := &packer.RemoteCmd{
|
||||
Command: fmt.Sprintf("mkdir -p '%s'", dir),
|
||||
}
|
||||
ui.Message(fmt.Sprintf("Creating directory: %s", dir))
|
||||
|
||||
cmd := &packer.RemoteCmd{Command: p.guestCommands.CreateDir(dir)}
|
||||
|
||||
if err := cmd.StartWithUi(comm, ui); err != nil {
|
||||
return err
|
||||
|
|
Loading…
Reference in New Issue