salt provisioner: tidy up and refactor into functions

This commit is contained in:
mafro 2014-08-07 15:07:27 +10:00
parent e7a46d97c0
commit ed07fb63e4
1 changed files with 68 additions and 37 deletions

View File

@ -8,6 +8,7 @@ import (
"github.com/mitchellh/packer/common"
"github.com/mitchellh/packer/packer"
"os"
"path/filepath"
)
const DefaultTempConfigDir = "/tmp/salt"
@ -108,6 +109,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
var err error
var src, dst string
ui.Say("Provisioning with Salt...")
if !p.config.SkipBootstrap {
@ -121,68 +123,58 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
}
ui.Message(fmt.Sprintf("Creating remote directory: %s", p.config.TempConfigDir))
cmd := &packer.RemoteCmd{Command: fmt.Sprintf("mkdir -p %s", p.config.TempConfigDir)}
if err = cmd.StartWithUi(comm, ui); err != nil || cmd.ExitStatus != 0 {
if err == nil {
err = fmt.Errorf("Bad exit status: %d", cmd.ExitStatus)
}
if err := p.createDir(ui, comm, p.config.TempConfigDir); err != nil {
return fmt.Errorf("Error creating remote salt state directory: %s", err)
}
if p.config.MinionConfig != "" {
ui.Message(fmt.Sprintf("Uploading minion config: %s", p.config.MinionConfig))
if err = uploadMinionConfig(comm, fmt.Sprintf("%s/minion", p.config.TempConfigDir), p.config.MinionConfig); err != nil {
src = p.config.MinionConfig
dst = filepath.ToSlash(filepath.Join(p.config.TempConfigDir, "minion"))
if err = p.uploadFile(ui, comm, dst, src); err != nil {
return fmt.Errorf("Error uploading local minion config file to remote: %s", err)
}
ui.Message(fmt.Sprintf("Moving %s/minion to /etc/salt/minion", p.config.TempConfigDir))
cmd = &packer.RemoteCmd{Command: fmt.Sprintf("sudo mv %s/minion /etc/salt/minion", p.config.TempConfigDir)}
if err = cmd.StartWithUi(comm, ui); err != nil || cmd.ExitStatus != 0 {
if err == nil {
err = fmt.Errorf("Bad exit status: %d", cmd.ExitStatus)
}
// move minion config into /etc/salt
src = filepath.ToSlash(filepath.Join(p.config.TempConfigDir, "minion"))
dst = "/etc/salt/minion"
if err = p.moveFile(ui, comm, dst, src); err != nil {
return fmt.Errorf("Unable to move %s/minion to /etc/salt/minion: %d", p.config.TempConfigDir, err)
}
}
ui.Message(fmt.Sprintf("Uploading local state tree: %s", p.config.LocalStateTree))
if err = comm.UploadDir(fmt.Sprintf("%s/states", p.config.TempConfigDir),
p.config.LocalStateTree, []string{".git"}); err != nil {
src = p.config.LocalStateTree
dst = filepath.ToSlash(filepath.Join(p.config.TempConfigDir, "states"))
if err = p.uploadDir(ui, comm, dst, src, []string{".git"}); err != nil {
return fmt.Errorf("Error uploading local state tree to remote: %s", err)
}
ui.Message(fmt.Sprintf("Moving %s/states to /srv/salt", p.config.TempConfigDir))
cmd = &packer.RemoteCmd{Command: fmt.Sprintf("sudo mv %s/states /srv/salt", p.config.TempConfigDir)}
if err = cmd.StartWithUi(comm, ui); err != nil || cmd.ExitStatus != 0 {
if err == nil {
err = fmt.Errorf("Bad exit status: %d", cmd.ExitStatus)
}
// move state tree into /srv/salt
src = filepath.ToSlash(filepath.Join(p.config.TempConfigDir, "states"))
dst = "/srv/salt"
if err = p.moveFile(ui, comm, dst, src); err != nil {
return fmt.Errorf("Unable to move %s/states to /srv/salt: %d", p.config.TempConfigDir, err)
}
if p.config.LocalPillarRoots != "" {
ui.Message(fmt.Sprintf("Uploading local pillar roots: %s", p.config.LocalPillarRoots))
if err = comm.UploadDir(fmt.Sprintf("%s/pillar", p.config.TempConfigDir),
p.config.LocalPillarRoots, []string{".git"}); err != nil {
src = p.config.LocalPillarRoots
dst = filepath.ToSlash(filepath.Join(p.config.TempConfigDir, "pillar"))
if err = p.uploadDir(ui, comm, dst, src, []string{".git"}); err != nil {
return fmt.Errorf("Error uploading local pillar roots to remote: %s", err)
}
ui.Message(fmt.Sprintf("Moving %s/pillar to /srv/pillar", p.config.TempConfigDir))
cmd = &packer.RemoteCmd{Command: fmt.Sprintf("sudo mv %s/pillar /srv/pillar", p.config.TempConfigDir)}
if err = cmd.StartWithUi(comm, ui); err != nil || cmd.ExitStatus != 0 {
if err == nil {
err = fmt.Errorf("Bad exit status: %d", cmd.ExitStatus)
}
// move pillar tree into /srv/pillar
src = filepath.ToSlash(filepath.Join(p.config.TempConfigDir, "pillar"))
dst = "/srv/pillar"
if err = p.moveFile(ui, comm, dst, src); err != nil {
return fmt.Errorf("Unable to move %s/pillar to /srv/pillar: %d", p.config.TempConfigDir, err)
}
}
ui.Message("Running highstate")
cmd = &packer.RemoteCmd{Command: "sudo salt-call --local state.highstate -l info"}
cmd := &packer.RemoteCmd{Command: "sudo salt-call --local state.highstate -l info"}
if err = cmd.StartWithUi(comm, ui); err != nil || cmd.ExitStatus != 0 {
if err == nil {
err = fmt.Errorf("Bad exit status: %d", cmd.ExitStatus)
@ -200,16 +192,55 @@ func (p *Provisioner) Cancel() {
os.Exit(0)
}
func uploadMinionConfig(comm packer.Communicator, dst string, src string) error {
func (p *Provisioner) uploadFile(ui packer.Ui, comm packer.Communicator, dst, src string) error {
f, err := os.Open(src)
if err != nil {
return fmt.Errorf("Error opening minion config: %s", err)
return fmt.Errorf("Error opening: %s", err)
}
defer f.Close()
if err = comm.Upload(dst, f, nil); err != nil {
return fmt.Errorf("Error uploading minion config: %s", err)
return fmt.Errorf("Error uploading %s: %s", src, err)
}
return nil
}
func (p *Provisioner) moveFile(ui packer.Ui, comm packer.Communicator, dst, src string) error {
ui.Message(fmt.Sprintf("Moving %s to %s", src, dst))
cmd := &packer.RemoteCmd{Command: fmt.Sprintf("sudo mv %s %s", src, dst)}
if err := cmd.StartWithUi(comm, ui); err != nil || cmd.ExitStatus != 0 {
if err == nil {
err = fmt.Errorf("Bad exit status: %d", cmd.ExitStatus)
}
return fmt.Errorf("Unable to move %s/minion to /etc/salt/minion: %d", p.config.TempConfigDir, err)
}
return nil
}
func (p *Provisioner) createDir(ui packer.Ui, comm packer.Communicator, dir string) error {
ui.Message(fmt.Sprintf("Creating directory: %s", dir))
cmd := &packer.RemoteCmd{
Command: fmt.Sprintf("mkdir -p '%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
}
// Make sure there is a trailing "/" so that the directory isn't
// created on the other side.
if src[len(src)-1] != '/' {
src = src + "/"
}
return comm.UploadDir(dst, src, ignore)
}