From 9ccf298be904c695cf414467bb4ca88b64b487b1 Mon Sep 17 00:00:00 2001 From: Matt Black Date: Sun, 23 Aug 2015 13:40:05 +0100 Subject: [PATCH] Salt provisioner: option to ignore salt highstate failures fixes #2486 --- provisioner/salt-masterless/provisioner.go | 11 +++++++-- .../salt-masterless/provisioner_test.go | 24 +++++++++++++++++++ .../salt-masterless.html.markdown | 3 +++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/provisioner/salt-masterless/provisioner.go b/provisioner/salt-masterless/provisioner.go index ce726630b..9c9d558a1 100644 --- a/provisioner/salt-masterless/provisioner.go +++ b/provisioner/salt-masterless/provisioner.go @@ -46,6 +46,9 @@ type Config struct { // Where files will be copied before moving to the /srv/salt directory TempConfigDir string `mapstructure:"temp_config_dir"` + // Don't exit packer if salt-call returns an error code + NoExitOnFailure bool `mapstructure:"no_exit_on_failure"` + // Command line args passed onto salt-call CmdArgs string "" @@ -92,7 +95,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { if p.config.MinionConfig != "" && (p.config.RemoteStateTree != "" || p.config.RemotePillarRoots != "") { errs = packer.MultiErrorAppend(errs, - errors.New("minion_config option overrides remote_state_tree and remote_pillar_roots")) + errors.New("remote_state_tree and remote_pillar_roots only apply when minion_config is not used")) } // build the command line args to pass onto salt @@ -116,6 +119,10 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { } } + if !p.config.NoExitOnFailure { + cmd_args.WriteString(" --retcode-passthrough") + } + p.config.CmdArgs = cmd_args.String() if errs != nil && len(errs.Errors) > 0 { @@ -217,7 +224,7 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { } ui.Message("Running highstate") - cmd := &packer.RemoteCmd{Command: p.sudo(fmt.Sprintf("salt-call --local state.highstate -l info --retcode-passthrough %s", p.config.CmdArgs))} + cmd := &packer.RemoteCmd{Command: p.sudo(fmt.Sprintf("salt-call --local state.highstate -l info %s", p.config.CmdArgs))} if err = cmd.StartWithUi(comm, ui); err != nil || cmd.ExitStatus != 0 { if err == nil { err = fmt.Errorf("Bad exit status: %d", cmd.ExitStatus) diff --git a/provisioner/salt-masterless/provisioner_test.go b/provisioner/salt-masterless/provisioner_test.go index 844f97c98..523e133b1 100644 --- a/provisioner/salt-masterless/provisioner_test.go +++ b/provisioner/salt-masterless/provisioner_test.go @@ -213,3 +213,27 @@ func TestProvisionerPrepare_RemotePillarRoots_Default(t *testing.T) { t.Fatal("--pillar-root should be set in CmdArgs") } } + +func TestProvisionerPrepare_NoExitOnFailure(t *testing.T) { + var p Provisioner + config := testConfig() + + err := p.Prepare(config) + if err != nil { + t.Fatalf("err: %s", err) + } + + if !strings.Contains(p.config.CmdArgs, "--retcode-passthrough") { + t.Fatal("--retcode-passthrough should be set in CmdArgs") + } + + config["no_exit_on_failure"] = true + err = p.Prepare(config) + if err != nil { + t.Fatalf("err: %s", err) + } + + if strings.Contains(p.config.CmdArgs, "--retcode-passthrough") { + t.Fatal("--retcode-passthrough should not be set in CmdArgs") + } +} diff --git a/website/source/docs/provisioners/salt-masterless.html.markdown b/website/source/docs/provisioners/salt-masterless.html.markdown index f671ec696..7abe7e633 100644 --- a/website/source/docs/provisioners/salt-masterless.html.markdown +++ b/website/source/docs/provisioners/salt-masterless.html.markdown @@ -68,3 +68,6 @@ Optional: - `temp_config_dir` (string) - Where your local state tree will be copied before moving to the `/srv/salt` directory. Default is `/tmp/salt`. + +- `no_exit_on_failure` (boolean) - Packer will exit if the Salt highstate command + fails. Set this option to true to ignore Salt failures.