gusteau 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,9 @@
1
+ ## 1.3.0 / 2013-12-05
2
+ * Add ability to configure Chef destination directory (`/etc/chef`) - [@omerisimo][], [#43][]
3
+ * More verbose list from `gusteau list` - [@locochris][], [#39][]
4
+ * Pass active node name into ENV for hook commands - [@anicholson][], [#36][]
5
+ * Unset GEM_HOME & GEM_PATH in omnibus script - [@ctaintor][], [#34][]
6
+
1
7
  ## 1.2.0 / 2013-07-17
2
8
  * Add ability to configure the version of Chef which will be bootstrapped - [@ctaintor][], [#30][]
3
9
  * Add 'box' configuration option for vagrant VMs - [@ctaintor][], [#29][]
@@ -46,5 +52,12 @@
46
52
  [#26]: https://github.com/locomote/gusteau/issues/26
47
53
  [#29]: https://github.com/locomote/gusteau/issues/29
48
54
  [#30]: https://github.com/locomote/gusteau/issues/30
55
+ [#34]: https://github.com/locomote/gusteau/issues/34
56
+ [#36]: https://github.com/locomote/gusteau/issues/36
57
+ [#39]: https://github.com/locomote/gusteau/issues/39
58
+ [#43]: https://github.com/locomote/gusteau/issues/43
59
+
49
60
  [@ctaintor]: https://github.com/ctaintor
50
61
  [@locochris]: https://github.com/locochris
62
+ [@anicholson]: https://github.com/anicholson
63
+ [@omerisimo]: https://github.com/omerisimo
data/README.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  *"Anyone can cook."*
4
4
 
5
- [![Build Status](https://www.travis-ci.org/locomote/gusteau.png?branch=master)](https://www.travis-ci.org/locomote/gusteau)
6
- [![Coverage Status](https://coveralls.io/repos/locomote/gusteau/badge.png)](https://coveralls.io/r/locomote/gusteau)
7
- [![Dependency Status](https://gemnasium.com/locomote/gusteau.png)](https://gemnasium.com/locomote/gusteau)
5
+ [![Build Status](https://travis-ci.org/locomote/gusteau.png?branch=master)](https://travis-ci.org/locomote/gusteau)
6
+ [![Coverage Status](https://coveralls.io/repos/locomote/gusteau/badge.png?branch=master)](https://coveralls.io/r/locomote/gusteau?branch=master)
7
+ [![Gem Version](https://badge.fury.io/rb/gusteau.png)](http://badge.fury.io/rb/gusteau)
8
8
 
9
9
  Gusteau is an easy to use configuration manager for Chef Solo and Vagrant. It aims to:
10
10
 
@@ -100,21 +100,22 @@ If you prefer calling ssh directly, you will find the `gusteau ssh_config` subco
100
100
  gusteau ssh_config >> ~/.ssh/config
101
101
  ```
102
102
 
103
- ## Vagrant
103
+ ## Vagrant Plugin
104
104
 
105
- Gusteau can save you from writing some Vagrantfile boilerplate code. It also enables you to move node-specific Vagrant configuration away from the Vagrantfile into node definitions.
105
+ Gusteau can save you from writing some Vagrantfile boilerplate code. It enables you to move node specific Vagrant configuration away from the Vagrantfile into node definitions. The Vagrant plugin for Gusteau means you can then bring up this node in VirtualBox.
106
106
 
107
107
  ```
108
- nodes:
109
- www:
110
- vagrant:
111
- IP: 192.168.100.20
112
- cpus: 1
113
- memory: 512
114
- box_url: 'https://opscode-vm.s3.amazonaws.com/vagrant/opscode_ubuntu-12.04_provisionerless.box'
108
+ development:
109
+ nodes:
110
+ www:
111
+ vagrant:
112
+ IP: 192.168.100.20
113
+ cpus: 1
114
+ memory: 512
115
+ box_url: 'https://opscode-vm.s3.amazonaws.com/vagrant/opscode_ubuntu-12.04_provisionerless.box'
115
116
  ```
116
117
 
117
- The following snippet configures Vagrant for all Gusteau nodes which have `vagrant` sections defined.
118
+ The following snippet in the Vagrantfile configures Vagrant for all nodes (as above) listed in Gusteau which have `vagrant` sections defined.
118
119
 
119
120
  ```ruby
120
121
  Vagrant.configure('2') do |config|
@@ -128,12 +129,18 @@ end
128
129
  * The `prefix` option lets you prepend your VirtualBox VMs names, e.g. `loco-nodename`.
129
130
  * The `defaults` one lets you provide default values for `cpus`, `memory`, `box_url`, `box`.
130
131
 
131
- Please note that the add-on only works with Vagrant ~> 1.2 and needs gusteau to be installed as a Vagrant plugin:
132
+ Please note that the add-on only works with Vagrant ~> 1.2 and needs Gusteau to be installed as a Vagrant plugin:
132
133
 
133
134
  ```
134
135
  vagrant plugin install gusteau
135
136
  ```
136
137
 
138
+ Once the Gusteau plugin for Vagrant is installed you can start up VirtualBox using the environment and node data for vagrant in .gusteau.yml:
139
+
140
+ ```
141
+ vagrant up development-www
142
+ ```
143
+
137
144
  ## Configuration
138
145
 
139
146
  ### Before and after hooks
@@ -192,3 +199,13 @@ By default, Gusteau uploads and sets Chef Solo up to use cookbooks from `./cookb
192
199
  cookbooks_path: [ './my-cookbooks', '../something-else' ]
193
200
  roles_path: './base-roles'
194
201
  ```
202
+
203
+ ### Custom Chef run configuration directory (e.g. `/etc/chef`)
204
+
205
+ By default, Gusteau uploads the necessary files and folders (i.e. cookbooks and roles directories) to `/etc/chef/`.
206
+
207
+ You can specify a custom target directory in `.gusteau.yml`:
208
+
209
+ ```
210
+ chef_config_dir: /etc/custom_chef_dir
211
+ ```
@@ -66,7 +66,7 @@ class Gusteau::CLI < Optitron::CLI
66
66
  end
67
67
 
68
68
  def nodes_list
69
- "Known nodes are:\n - #{nodes.keys.join("\n - ")}"
69
+ "Known nodes are:\n - #{nodes.values.join("\n - ")}"
70
70
  end
71
71
 
72
72
  end
@@ -5,7 +5,7 @@ install_sh="https://www.opscode.com/chef/install.sh"
5
5
  requested_version=$1
6
6
 
7
7
  if type -p chef-solo > /dev/null; then
8
- installed_version=$(chef-solo --v | awk '{print $2}')
8
+ installed_version=$(unset GEM_HOME; unset GEM_PATH; chef-solo --v | awk '{print $2}')
9
9
  fi
10
10
  if [ $installed_version == $requested_version ]; then
11
11
  echo "Using chef-solo $installed_version at $(which chef-solo)"
@@ -0,0 +1,7 @@
1
+ <% dest_dir = Gusteau::Config.settings['chef_config_dir'] %>
2
+ file_cache_path "/tmp/chef"
3
+ cookbook_path *Dir.glob("<%= dest_dir %>/cookbooks-*")
4
+ role_path "<%= dest_dir %>/roles"
5
+ data_bag_path "<%= dest_dir %>/data_bags"
6
+
7
+ log_level :info
@@ -11,6 +11,7 @@ Gem::Specification.new do |gem|
11
11
  gem.description = %q{Chef Solo wrapper and configuration manager}
12
12
  gem.summary = %q{Making servers provisioning enjoyable since 2013.}
13
13
  gem.homepage = "http://gusteau.gs"
14
+ gem.licenses = %w{ BSD MIT }
14
15
 
15
16
  gem.files = `git ls-files | grep -vE '(jenkins|.gitmodules|.ruby-version)'`.split("\n")
16
17
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
@@ -1,22 +1,25 @@
1
+ require 'gusteau/erb'
2
+
1
3
  module Gusteau
2
4
  class Chef
5
+ include Gusteau::ERB
3
6
 
4
- def initialize(server, platform = nil, dest_dir = '/etc/chef')
7
+ def initialize(server, platform = nil)
5
8
  @server = server
6
9
  @platform = platform || 'omnibus'
7
- @dest_dir = dest_dir
8
10
  end
9
11
 
10
12
  def run(dna, opts)
11
- @server.run "rm -rf #{@dest_dir} && mkdir #{@dest_dir} && mkdir -p /tmp/chef"
13
+ dest_dir = Gusteau::Config.settings['chef_config_dir']
14
+ @server.run "rm -rf #{dest_dir} && mkdir #{dest_dir} && mkdir -p /tmp/chef"
12
15
 
13
16
  with_gusteau_dir(dna[:path]) do |dir|
14
- @server.upload [dir], @dest_dir, :exclude => '.git/', :strip_c => 2
17
+ @server.upload [dir], dest_dir, :exclude => '.git/', :strip_c => 2
15
18
  end
16
19
 
17
20
  @server.run "sh /etc/chef/bootstrap.sh #{Gusteau::Config.settings['chef_version']}" if opts['bootstrap']
18
21
 
19
- cmd = "unset GEM_HOME; unset GEM_PATH; chef-solo -c #{@dest_dir}/solo.rb -j #{@dest_dir}/dna.json --color"
22
+ cmd = "unset GEM_HOME; unset GEM_PATH; chef-solo -c #{dest_dir}/solo.rb -j #{dest_dir}/dna.json --color"
20
23
  cmd << " -F #{opts['format']}" if opts['format']
21
24
  cmd << " -l #{opts['log_level']}" if opts['log_level']
22
25
  cmd << " -W" if opts['why-run']
@@ -32,7 +35,7 @@ module Gusteau
32
35
  {
33
36
  dna_path => "dna.json",
34
37
  bootstrap => "bootstrap.sh",
35
- "#{bootstrap_dir}/solo.rb" => "solo.rb",
38
+ "#{bootstrap_dir}/solo.rb.erb" => "solo.rb",
36
39
  'data_bags' => "data_bags",
37
40
  Gusteau::Config.settings['roles_path'] => "roles"
38
41
  }.tap do |f|
@@ -47,7 +50,15 @@ module Gusteau
47
50
  FileUtils.mkdir_p(tmp_dir)
48
51
 
49
52
  files_list(dna_path).each_pair do |src, dest|
50
- FileUtils.cp_r(src, "#{tmp_dir}/#{dest}") if File.exists?(src)
53
+ if File.exists?(src)
54
+ if File.extname(src) == '.erb'
55
+ File.open("#{tmp_dir}/#{dest}", "w" ) do |f|
56
+ f.write read_erb(src)
57
+ end
58
+ else
59
+ FileUtils.cp_r(src, "#{tmp_dir}/#{dest}")
60
+ end
61
+ end
51
62
  end
52
63
 
53
64
  yield tmp_dir
@@ -4,6 +4,7 @@ require 'gusteau/helpers'
4
4
  module Gusteau
5
5
  class Config
6
6
  DEFAULT_CHEF_VERSION = '11.4.4'
7
+ DEFAULT_CHEF_CONFIG_DIRECTORY = '/etc/chef'
7
8
 
8
9
  include Gusteau::ERB
9
10
 
@@ -45,10 +46,11 @@ module Gusteau
45
46
 
46
47
  def settings
47
48
  {
48
- 'cookbooks_path' => @config['cookbooks_path'] || ['cookbooks', 'site-cookbooks'],
49
- 'roles_path' => @config['roles_path'] || 'roles',
50
- 'bootstrap' => @config['bootstrap'],
51
- 'chef_version' => @config['chef_version'] || DEFAULT_CHEF_VERSION
49
+ 'cookbooks_path' => @config['cookbooks_path'] || ['cookbooks', 'site-cookbooks'],
50
+ 'roles_path' => @config['roles_path'] || 'roles',
51
+ 'bootstrap' => @config['bootstrap'],
52
+ 'chef_version' => @config['chef_version'] || DEFAULT_CHEF_VERSION,
53
+ 'chef_config_dir' => @config['chef_config_dir'] || DEFAULT_CHEF_CONFIG_DIRECTORY
52
54
  }
53
55
  end
54
56
 
@@ -14,6 +14,10 @@ module Gusteau
14
14
  @dna_path = '/tmp/dna.json'
15
15
  end
16
16
 
17
+ def to_s
18
+ "#{name} (#{@server})"
19
+ end
20
+
17
21
  def converge(opts = {})
18
22
  with_hooks do
19
23
  server.chef.run dna, opts
@@ -40,7 +44,7 @@ module Gusteau
40
44
 
41
45
  def hook(hook_type)
42
46
  (@config[hook_type] || []).each do |cmd|
43
- Kernel.system cmd
47
+ Kernel.system({ 'GUSTEAU_NODE' => name }, cmd)
44
48
  unless $?.exitstatus == 0
45
49
  log_error "Error executing a #{hook_type} hook: '#{cmd}'"
46
50
  exit 1
@@ -17,6 +17,10 @@ module Gusteau
17
17
  @chef = Gusteau::Chef.new(self, config['platform'])
18
18
  end
19
19
 
20
+ def to_s
21
+ "#{user}@#{host}#{" -p #{port}" unless port == 22}"
22
+ end
23
+
20
24
  def upload(files_and_dirs, dest_dir, opts={})
21
25
  log "#uploading #{files_and_dirs.join(' ')} to #{@host}:#{dest_dir}" do
22
26
  files = []
@@ -1,3 +1,3 @@
1
1
  module Gusteau
2
- VERSION = "1.2.0"
2
+ VERSION = "1.3.0"
3
3
  end
@@ -7,3 +7,5 @@ roles_path: basic-roles
7
7
  bootstrap: ./bootstrap/osx.sh
8
8
 
9
9
  chef_version: 10.26.0
10
+
11
+ chef_config_dir: /etc/custom_chef_dir
@@ -36,6 +36,11 @@ describe Gusteau::Chef do
36
36
  chef.run({ :path => '/tmp/node.json' }, opts)
37
37
  end
38
38
  end
39
+
40
+ it "removes and creates the chef configuration directory" do
41
+ server.expects(:run).with("rm -rf /etc/custom_chef_dir && mkdir /etc/custom_chef_dir && mkdir -p /tmp/chef")
42
+ chef.run({ :path => '/tmp/node.json' }, opts)
43
+ end
39
44
  end
40
45
 
41
46
  describe "#files_list" do
@@ -48,4 +53,24 @@ describe Gusteau::Chef do
48
53
  subject['./bootstrap/osx.sh'].must_equal 'bootstrap.sh'
49
54
  end
50
55
  end
56
+
57
+ describe "#with_gusteau_dir" do
58
+ it "copies files to the tmp directory" do
59
+ File.stubs(:exists?).returns(true)
60
+ chef.send(:files_list, '/some/dna.json').each_pair do |src, dest|
61
+ # Expect to copy the files listed by #files_list (excpet for .erb)
62
+ FileUtils.expects(:cp_r).with(src, regexp_matches( %r{^/tmp/gusteau-\d{10}/#{dest}$} )) unless File.extname(src) == '.erb'
63
+ end
64
+
65
+ chef.send(:with_gusteau_dir, '/some/dna.json') {}
66
+ end
67
+
68
+ it "process the solo.rb.erb with ERB template and saves the result to the tmp directory" do
69
+ file_mock = mock
70
+ file_mock.expects(:write).with(regexp_matches( %r{/etc/custom_chef_dir} )) # Expect the value from emile.yml:chef_config_dir
71
+ File.expects(:open).with(regexp_matches( %r{^/tmp/gusteau-\d{10}/solo.rb$} ),"w").yields(file_mock)
72
+
73
+ chef.send(:with_gusteau_dir, '/some/dna.json') {}
74
+ end
75
+ end
51
76
  end
@@ -41,11 +41,12 @@ describe Gusteau::Config do
41
41
  describe "#settings" do
42
42
  let(:settings) { Gusteau::Config.settings }
43
43
 
44
- it "should have defaults for cookbooks_path, roles_path, bootstrap, chef_version" do
44
+ it "should have defaults for cookbooks_path, roles_path, bootstrap, chef_version, chef_config_dir" do
45
45
  settings['cookbooks_path'].must_equal ['cookbooks', 'site-cookbooks']
46
46
  settings['roles_path'].must_equal 'roles'
47
47
  settings['bootstrap'].must_equal nil
48
48
  settings['chef_version'].must_equal Gusteau::Config::DEFAULT_CHEF_VERSION
49
+ settings['chef_config_dir'].must_equal Gusteau::Config::DEFAULT_CHEF_CONFIG_DIRECTORY
49
50
  end
50
51
 
51
52
  context "settings defined in the config yml" do
@@ -55,6 +56,7 @@ describe Gusteau::Config do
55
56
  settings['cookbooks_path'].must_equal ['private-cookbooks', '/home/user/.cookbooks']
56
57
  settings['roles_path'].must_equal 'basic-roles'
57
58
  settings['chef_version'].must_equal '10.26.0'
59
+ settings['chef_config_dir'].must_equal '/etc/custom_chef_dir'
58
60
  end
59
61
  end
60
62
  end
@@ -67,8 +67,8 @@ describe Gusteau::Node do
67
67
 
68
68
  describe "#hook" do
69
69
  it "should execute system commands" do
70
- Kernel.expects(:system).with('bundle')
71
- Kernel.expects(:system).with('vagrant up')
70
+ Kernel.expects(:system).with({'GUSTEAU_NODE' => 'test'}, 'bundle')
71
+ Kernel.expects(:system).with({'GUSTEAU_NODE' => 'test'}, 'vagrant up')
72
72
  node.server.chef.expects(:run)
73
73
  node.apply([], {})
74
74
  end
@@ -81,4 +81,10 @@ describe Gusteau::Node do
81
81
  end
82
82
  end
83
83
  end
84
+
85
+ describe "#to_s" do
86
+ it "returns a node name and an SSH connection string" do
87
+ node.to_s.must_equal 'test (root@example.com)'
88
+ end
89
+ end
84
90
  end
@@ -85,4 +85,10 @@ describe Gusteau::Server do
85
85
  server.ssh
86
86
  end
87
87
  end
88
+
89
+ describe "#to_s" do
90
+ it "returns an SSH connection string" do
91
+ server.to_s.must_equal 'root@demo.com -p 2222'
92
+ end
93
+ end
88
94
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gusteau
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-07-17 00:00:00.000000000 Z
13
+ date: 2013-12-05 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: optitron
@@ -241,7 +241,7 @@ files:
241
241
  - bin/gusteau_ssh_expect
242
242
  - bootstrap/gentoo.sh
243
243
  - bootstrap/omnibus.sh
244
- - bootstrap/solo.rb
244
+ - bootstrap/solo.rb.erb
245
245
  - gusteau.gemspec
246
246
  - lib/gusteau.rb
247
247
  - lib/gusteau/bureau.rb
@@ -289,7 +289,9 @@ files:
289
289
  - template/spec/example-box/platform_spec.rb.erb
290
290
  - template/spec/spec_helper.rb
291
291
  homepage: http://gusteau.gs
292
- licenses: []
292
+ licenses:
293
+ - BSD
294
+ - MIT
293
295
  post_install_message:
294
296
  rdoc_options: []
295
297
  require_paths:
@@ -300,18 +302,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
300
302
  - - ! '>='
301
303
  - !ruby/object:Gem::Version
302
304
  version: '0'
303
- segments:
304
- - 0
305
- hash: 325111124965789744
306
305
  required_rubygems_version: !ruby/object:Gem::Requirement
307
306
  none: false
308
307
  requirements:
309
308
  - - ! '>='
310
309
  - !ruby/object:Gem::Version
311
310
  version: '0'
312
- segments:
313
- - 0
314
- hash: 325111124965789744
315
311
  requirements: []
316
312
  rubyforge_project:
317
313
  rubygems_version: 1.8.23
@@ -1,6 +0,0 @@
1
- file_cache_path "/tmp/chef"
2
- cookbook_path *Dir.glob("/etc/chef/cookbooks-*")
3
- role_path "/etc/chef/roles"
4
- data_bag_path "/etc/chef/data_bags"
5
-
6
- log_level :info