From 4b2d1efb131b7e6cc78a5f4b0a60a2cee6293b97 Mon Sep 17 00:00:00 2001 From: Rachid Belaid Date: Sat, 10 Aug 2013 18:20:02 +0100 Subject: [PATCH] Fix #264 to upload local minion config Conflicts: provisioner/salt-masterless/provisioner.go website/source/docs/provisioners/salt.html.markdown --- provisioner/salt-masterless/provisioner.go | 35 +++++++++++++ .../salt-masterless/provisioner_test.go | 24 +++++++++ .../salt-masterless.html.markdown | 4 ++ .../docs/provisioners/salt.html.markdown | 51 +++++++++++++++++++ 4 files changed, 114 insertions(+) create mode 100644 website/source/docs/provisioners/salt.html.markdown diff --git a/provisioner/salt-masterless/provisioner.go b/provisioner/salt-masterless/provisioner.go index 982eabebf..bc98b5e37 100644 --- a/provisioner/salt-masterless/provisioner.go +++ b/provisioner/salt-masterless/provisioner.go @@ -21,6 +21,9 @@ type Config struct { SkipBootstrap bool `mapstructure:"skip_bootstrap"` BootstrapArgs string `mapstructure:"bootstrap_args"` + // Local path to the minion config + MinionConfig string `mapstructure:"minion_config"` + // Local path to the salt state tree LocalStateTree string `mapstructure:"local_state_tree"` @@ -55,6 +58,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { templates := map[string]*string{ "bootstrap_args": &p.config.BootstrapArgs, + "minion_config": &p.config.MinionConfig, "local_state_tree": &p.config.LocalStateTree, "temp_config_dir": &p.config.TempConfigDir, } @@ -75,6 +79,13 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { } } + if p.config.MinionConfig != "" { + if _, err := os.Stat(p.config.MinionConfig); err != nil { + errs = packer.MultiErrorAppend(errs, + errors.New("minion_config must exist and be accessible")) + } + } + if errs != nil && len(errs.Errors) > 0 { return errs } @@ -96,6 +107,17 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { } } + if p.config.MinionConfig != "" { + err := uploadMinionConfig(comm, "/etc/salt/minion", p.config.MinionConfig) + if err != nil { + return err + } + } + + if err = UploadLocalDirectory(p.config.LocalStateTree, p.config.TempConfigDir, comm, ui); err != nil { + return fmt.Errorf("Error uploading local state tree to remote: %s", err) + } + 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 { @@ -171,3 +193,16 @@ func UploadLocalDirectory(localDir string, remoteDir string, comm packer.Communi return nil } + +func uploadMinionConfig(comm packer.Communicator, dst string, src string) error { + ui.Message(fmt.Sprintf("Uploading minion config: %s", src)) + f, err := os.Open(src) + if err != nil { + return fmt.Errorf("Error opening minion config: %s", err) + } + defer f.Close() + + if err = comm.Upload(dst, f); err != nil { + return fmt.Errorf("Error uploading minion config: %s", err) + } +} diff --git a/provisioner/salt-masterless/provisioner_test.go b/provisioner/salt-masterless/provisioner_test.go index 59c2fedeb..06bca0754 100644 --- a/provisioner/salt-masterless/provisioner_test.go +++ b/provisioner/salt-masterless/provisioner_test.go @@ -2,6 +2,7 @@ package saltmasterless import ( "github.com/mitchellh/packer/packer" + "io/ioutil" "os" "testing" ) @@ -46,6 +47,29 @@ func TestProvisionerPrepare_InvalidKey(t *testing.T) { } } +func TestProvisionerPrepare_MinionConfig(t *testing.T) { + var p Provisioner + config := testConfig() + + config["minion_config"] = "/i/dont/exist/i/think" + err := p.Prepare(config) + if err == nil { + t.Fatal("should have error") + } + + tf, err := ioutil.TempFile("", "minion") + if err != nil { + t.Fatalf("error tempfile: %s", err) + } + defer os.Remove(tf.Name()) + + config["minion_config"] = tf.Name() + err = p.Prepare(config) + if err != nil { + t.Fatalf("err: %s", err) + } +} + func TestProvisionerPrepare_LocalStateTree(t *testing.T) { var p Provisioner config := testConfig() diff --git a/website/source/docs/provisioners/salt-masterless.html.markdown b/website/source/docs/provisioners/salt-masterless.html.markdown index 84e6f09ec..29009f671 100644 --- a/website/source/docs/provisioners/salt-masterless.html.markdown +++ b/website/source/docs/provisioners/salt-masterless.html.markdown @@ -40,5 +40,9 @@ Optional: has more detailed usage instructions. By default, no arguments are sent to the script. +* `minion_config` (string) - The path to your local + [minion config](http://docs.saltstack.com/topics/configuration.html). + This will be uploaded to the `/etc/salt` on the remote. + * `temp_config_dir` (string) - Where your local state tree will be copied before moving to the `/srv/salt` directory. Default is `/tmp/salt`. diff --git a/website/source/docs/provisioners/salt.html.markdown b/website/source/docs/provisioners/salt.html.markdown new file mode 100644 index 000000000..3b99019aa --- /dev/null +++ b/website/source/docs/provisioners/salt.html.markdown @@ -0,0 +1,51 @@ +--- +layout: "docs" +--- + +# Salt Masterless Provisioner + +Type: `salt-masterless` + +The `salt-masterless` provisioner provisions machines built by Packer using +[Salt](http://saltstack.com/) states, without connecting to a Salt master. + +## Basic Example + +The example below is fully functional. + +
+{
+    "type": "salt-masterless",
+    "local_state_tree": "/Users/me/salt"
+}
+
+ +## Configuration Reference + +The reference of available configuration options is listed below. The only required argument is the path to your local salt state tree. + +Required: + +* `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, and removed before + shutdown. + +Optional: + +* `skip_bootstrap` (boolean) - By default the salt provisioner runs + [salt bootstrap](https://github.com/saltstack/salt-bootstrap) to install + salt. Set this to true to skip this step. + +* `boostrap_args` (string) - Arguments to send to the bootstrap script. Usage + is somewhat documented on [github](https://github.com/saltstack/salt-bootstrap), + but the [script itself](https://github.com/saltstack/salt-bootstrap/blob/develop/bootstrap-salt.sh) + has more detailed usage instructions. By default, no arguments are sent to + the script. + +* `temp_config_dir` (string) - Where your local state tree will be copied + before moving to the `/srv/salt` directory. Default is `/tmp/salt`. + +* `minion_config` (string) - The path to your local + [minion config](http://docs.saltstack.com/topics/configuration.html). + This will be uploaded to the `/etc/salt` on the remote.