diff --git a/provisioner/salt-masterless/provisioner.go b/provisioner/salt-masterless/provisioner.go index 1f6567c4a..1ec740018 100644 --- a/provisioner/salt-masterless/provisioner.go +++ b/provisioner/salt-masterless/provisioner.go @@ -15,6 +15,8 @@ import ( ) const DefaultTempConfigDir = "/tmp/salt" +const DefaultStateTreeDir = "/srv/salt" +const DefaultPillarRootDir = "/srv/pillar" type Config struct { common.PackerConfig `mapstructure:",squash"` @@ -34,6 +36,12 @@ type Config struct { // Local path to the salt pillar roots LocalPillarRoots string `mapstructure:"local_pillar_roots"` + // Remote path to the salt state tree + RemoteStateTree string `mapstructure:"remote_state_tree"` + + // Remote path to the salt pillar roots + RemotePillarRoots string `mapstructure:"remote_pillar_roots"` + // Where files will be copied before moving to the /srv/salt directory TempConfigDir string `mapstructure:"temp_config_dir"` @@ -60,6 +68,14 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { p.config.TempConfigDir = DefaultTempConfigDir } + if p.config.RemoteStateTree == "" { + p.config.RemoteStateTree = DefaultStateTreeDir + } + + if p.config.RemotePillarRoots == "" { + p.config.RemotePillarRoots = DefaultPillarRootDir + } + var errs *packer.MultiError // require a salt state tree @@ -148,11 +164,14 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { return fmt.Errorf("Error uploading local state tree to remote: %s", err) } - // move state tree into /srv/salt + // move state tree from temporary directory src = filepath.ToSlash(filepath.Join(p.config.TempConfigDir, "states")) - dst = "/srv/salt" + dst = p.config.RemoteStateTree + if err = p.removeDir(ui, comm, dst); err != nil { + return fmt.Errorf("Unable to clear salt tree: %s", err) + } if err = p.moveFile(ui, comm, dst, src); err != nil { - return fmt.Errorf("Unable to move %s/states to /srv/salt: %s", p.config.TempConfigDir, err) + return fmt.Errorf("Unable to move %s/states to %s: %s", p.config.TempConfigDir, dst, err) } if p.config.LocalPillarRoots != "" { @@ -163,16 +182,19 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { return fmt.Errorf("Error uploading local pillar roots to remote: %s", err) } - // move pillar tree into /srv/pillar + // move pillar root from temporary directory src = filepath.ToSlash(filepath.Join(p.config.TempConfigDir, "pillar")) - dst = "/srv/pillar" + dst = p.config.RemotePillarRoots + if err = p.removeDir(ui, comm, dst); err != nil { + return fmt.Errorf("Unable to clear pillat root: %s", err) + } if err = p.moveFile(ui, comm, dst, src); err != nil { - return fmt.Errorf("Unable to move %s/pillar to /srv/pillar: %s", p.config.TempConfigDir, err) + return fmt.Errorf("Unable to move %s/pillar to %s: %s", p.config.TempConfigDir, dst, err) } } ui.Message("Running highstate") - cmd := &packer.RemoteCmd{Command: p.sudo("salt-call --local state.highstate -l info --retcode-passthrough")} + cmd := &packer.RemoteCmd{Command: fmt.Sprintf(p.sudo("salt-call --local state.highstate --file-root=%s --pillar-root=%s -l info --retcode-passthrough"),p.config.RemoteStateTree, p.config.RemotePillarRoots)} if err = cmd.StartWithUi(comm, ui); err != nil || cmd.ExitStatus != 0 { if err == nil { err = fmt.Errorf("Bad exit status: %d", cmd.ExitStatus) @@ -239,6 +261,20 @@ 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 { + ui.Message(fmt.Sprintf("Removing directory: %s", dir)) + cmd := &packer.RemoteCmd{ + Command: fmt.Sprintf("rm -rf '%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) uploadDir(ui packer.Ui, comm packer.Communicator, dst, src string, ignore []string) error { if err := p.createDir(ui, comm, dst); err != nil { return err diff --git a/website/source/docs/provisioners/salt-masterless.html.markdown b/website/source/docs/provisioners/salt-masterless.html.markdown index 679a0f6eb..1eeabaf14 100644 --- a/website/source/docs/provisioners/salt-masterless.html.markdown +++ b/website/source/docs/provisioners/salt-masterless.html.markdown @@ -38,13 +38,21 @@ Optional: has more detailed usage instructions. By default, no arguments are sent to the script. +- `remote_pillar_roots` (string) - The path to your remote [pillar + roots](http://docs.saltstack.com/ref/configuration/master.html#pillar-configuration). + default: `/srv/pillar`. + +- `remote_state_tree` (string) - The path to your remote [state + tree](http://docs.saltstack.com/ref/states/highstate.html#the-salt-state-tree). + default: `/srv/salt`. + - `local_pillar_roots` (string) - The path to your local [pillar roots](http://docs.saltstack.com/ref/configuration/master.html#pillar-configuration). - This will be uploaded to the `/srv/pillar` on the remote. + This will be uploaded to the `remote_pillar_roots` on the remote. - `local_state_tree` (string) - The path to your local [state tree](http://docs.saltstack.com/ref/states/highstate.html#the-salt-state-tree). - This will be uploaded to the `/srv/salt` on the remote. + This will be uploaded to the `remote_state_tree` on the remote. - `minion_config` (string) - The path to your local [minion config file](http://docs.saltstack.com/ref/configuration/minion.html). This will be