Merge pull request #1394 from mafrosis/salt-masterless

Salt masterless tidy up
This commit is contained in:
Mitchell Hashimoto 2014-10-28 08:35:10 -07:00
commit 81d8cd0db4
1 changed files with 73 additions and 38 deletions

View File

@ -8,6 +8,7 @@ import (
"github.com/mitchellh/packer/common" "github.com/mitchellh/packer/common"
"github.com/mitchellh/packer/packer" "github.com/mitchellh/packer/packer"
"os" "os"
"path/filepath"
) )
const DefaultTempConfigDir = "/tmp/salt" const DefaultTempConfigDir = "/tmp/salt"
@ -74,7 +75,11 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
} }
} }
if p.config.LocalStateTree != "" { // require a salt state tree
if p.config.LocalStateTree == "" {
errs = packer.MultiErrorAppend(errs,
errors.New("local_state_tree must be supplied"))
} else {
if _, err := os.Stat(p.config.LocalStateTree); err != nil { if _, err := os.Stat(p.config.LocalStateTree); err != nil {
errs = packer.MultiErrorAppend(errs, errs = packer.MultiErrorAppend(errs,
errors.New("local_state_tree must exist and be accessible")) errors.New("local_state_tree must exist and be accessible"))
@ -104,6 +109,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
var err error var err error
var src, dst string
ui.Say("Provisioning with Salt...") ui.Say("Provisioning with Salt...")
if !p.config.SkipBootstrap { if !p.config.SkipBootstrap {
@ -117,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)) 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 := p.createDir(ui, comm, p.config.TempConfigDir); err != nil {
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("Error creating remote salt state directory: %s", err) return fmt.Errorf("Error creating remote salt state directory: %s", err)
} }
if p.config.MinionConfig != "" { if p.config.MinionConfig != "" {
ui.Message(fmt.Sprintf("Uploading minion config: %s", 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) 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)) // move minion config into /etc/salt
cmd = &packer.RemoteCmd{Command: fmt.Sprintf("sudo mv %s/minion /etc/salt/minion", p.config.TempConfigDir)} src = filepath.ToSlash(filepath.Join(p.config.TempConfigDir, "minion"))
if err = cmd.StartWithUi(comm, ui); err != nil || cmd.ExitStatus != 0 { dst = "/etc/salt/minion"
if err == nil { if err = p.moveFile(ui, comm, dst, src); 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 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)) ui.Message(fmt.Sprintf("Uploading local state tree: %s", p.config.LocalStateTree))
if err = comm.UploadDir(fmt.Sprintf("%s/states", p.config.TempConfigDir), src = p.config.LocalStateTree
p.config.LocalStateTree, []string{".git"}); err != nil { 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) 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)) // move state tree into /srv/salt
cmd = &packer.RemoteCmd{Command: fmt.Sprintf("sudo mv %s/states /srv/salt", p.config.TempConfigDir)} src = filepath.ToSlash(filepath.Join(p.config.TempConfigDir, "states"))
if err = cmd.StartWithUi(comm, ui); err != nil || cmd.ExitStatus != 0 { dst = "/srv/salt"
if err == nil { if err = p.moveFile(ui, comm, dst, src); err != nil {
err = fmt.Errorf("Bad exit status: %d", cmd.ExitStatus)
}
return fmt.Errorf("Unable to move %s/states to /srv/salt: %d", p.config.TempConfigDir, err) return fmt.Errorf("Unable to move %s/states to /srv/salt: %d", p.config.TempConfigDir, err)
} }
if p.config.LocalPillarRoots != "" { if p.config.LocalPillarRoots != "" {
ui.Message(fmt.Sprintf("Uploading local pillar roots: %s", 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), src = p.config.LocalPillarRoots
p.config.LocalPillarRoots, []string{".git"}); err != nil { 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) 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)) // move pillar tree into /srv/pillar
cmd = &packer.RemoteCmd{Command: fmt.Sprintf("sudo mv %s/pillar /srv/pillar", p.config.TempConfigDir)} src = filepath.ToSlash(filepath.Join(p.config.TempConfigDir, "pillar"))
if err = cmd.StartWithUi(comm, ui); err != nil || cmd.ExitStatus != 0 { dst = "/srv/pillar"
if err == nil { if err = p.moveFile(ui, comm, dst, src); err != nil {
err = fmt.Errorf("Bad exit status: %d", cmd.ExitStatus)
}
return fmt.Errorf("Unable to move %s/pillar to /srv/pillar: %d", p.config.TempConfigDir, err) return fmt.Errorf("Unable to move %s/pillar to /srv/pillar: %d", p.config.TempConfigDir, err)
} }
} }
ui.Message("Running highstate") 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 = cmd.StartWithUi(comm, ui); err != nil || cmd.ExitStatus != 0 {
if err == nil { if err == nil {
err = fmt.Errorf("Bad exit status: %d", cmd.ExitStatus) err = fmt.Errorf("Bad exit status: %d", cmd.ExitStatus)
@ -196,16 +192,55 @@ func (p *Provisioner) Cancel() {
os.Exit(0) 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) f, err := os.Open(src)
if err != nil { if err != nil {
return fmt.Errorf("Error opening minion config: %s", err) return fmt.Errorf("Error opening: %s", err)
} }
defer f.Close() defer f.Close()
if err = comm.Upload(dst, f, nil); err != nil { 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 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)
}