motherbrain 0.14.4 → 0.14.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d2a478e99e516d43785867b8e067d0dc47ea676c
4
- data.tar.gz: 3b13b3e672777cc022ab3ffa2a7d789fb066b36e
3
+ metadata.gz: 45f24209faef88c327c3979ebdf59cdc961bf530
4
+ data.tar.gz: 49f3bbdb3c81b052aa3a1eddfdc1256427818653
5
5
  SHA512:
6
- metadata.gz: 8357c35313e3402ca32181ff777f9498c387306545d5d1619267127b0481b479b228243d48051648d4ffeece01c46c5c70c24d8bc4e8c6642483c1b9ecce217b
7
- data.tar.gz: 672b31a6fb744bdca06e4a235f7a8c6594d1bb0db29dfa515981721f40a19c44d8b7ed4bdd9d73ea0f8cfbcbc543d6e41284b613cd140357b4d1bb97ba351351
6
+ metadata.gz: e50ad349193026c2bd4c221e6ec3e9a78729c6dc1304bfe130a6f0be20d2011d3f480f708926a3cb73410790e833b98b9da2aec831d881948ab1ad3d23273145
7
+ data.tar.gz: e32e2999bbfb6157237bfffd0a3fc1320f0bd1ce4164ee35960fd6c0b3046ceb77b490d538f31e53aa2d5fbf5638227d297fa98a46d2b803f47f4179d14ec466
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ # 0.14.5
2
+
3
+ * Use run_list instead of roles/recipes
4
+
5
+ # 0.14.4
6
+
7
+ * Use newer ridley-connectors
8
+ * Profiling options
9
+ * Issue #665 - Use cookbook versions found Berksfile.lock if found
10
+
1
11
  # 0.13.1
2
12
 
3
13
  * Depend on faraday < 0.9
data/Gemfile CHANGED
@@ -22,7 +22,7 @@ group :development do
22
22
  gem 'ronn', platforms: :ruby
23
23
  gem 'chef-zero', '~> 1.5.0'
24
24
  gem 'pry-nav'
25
- gem 'ruby-prof'
25
+ gem 'ruby-prof', platforms: :ruby
26
26
  end
27
27
 
28
28
  group :test do
data/lib/mb/berkshelf.rb CHANGED
@@ -46,5 +46,36 @@ module MotherBrain
46
46
  Pathname.new(Application.config.berkshelf.path || default_path)
47
47
  end
48
48
  end
49
+
50
+ # A wrapper around the berkshelf's Berkshelf::Lockfile
51
+ class Lockfile
52
+ include MB::Logging
53
+
54
+ BERKSFILE_LOCK = 'Berksfile.lock'.freeze
55
+
56
+ class << self
57
+ def from_path(root_path)
58
+ new(File.join(root_path, BERKSFILE_LOCK))
59
+ end
60
+ end
61
+
62
+ attr_reader :berksfile_lock
63
+
64
+ def initialize(berksfile_lock_path)
65
+ @berksfile_lock = ::Berkshelf::Lockfile.from_file(berksfile_lock_path)
66
+ end
67
+
68
+ # Return a hash of all of the cookbook versions found in the Berksfile.lock
69
+ # The key is the name of the cookbook and the value is the version as a
70
+ # String. If there is no lockfile an empty hash is returned.
71
+ #
72
+ # @return [Hash]
73
+ def locked_versions
74
+ berksfile_lock.graph.locks.inject({}) do |hash, (name, dependency)|
75
+ hash[name] = dependency.locked_version.to_s
76
+ hash
77
+ end
78
+ end
79
+ end
49
80
  end
50
81
  end
@@ -76,7 +76,6 @@ module MotherBrain
76
76
  # @see {#async_bootstrap} for options
77
77
  def bootstrap(job, environment, manifest, plugin, options = {})
78
78
  options = options.reverse_merge(
79
- cookbook_versions: Hash.new,
80
79
  component_versions: Hash.new,
81
80
  environment_attributes: Hash.new,
82
81
  hints: Hash.new,
@@ -104,9 +103,10 @@ module MotherBrain
104
103
  set_component_versions(environment, plugin, options[:component_versions])
105
104
  end
106
105
 
107
- if options[:cookbook_versions].any?
106
+ cookbook_versions = options[:cookbook_versions] || plugin.cookbook_versions
107
+ if cookbook_versions.any?
108
108
  job.set_status("Setting cookbook versions")
109
- set_cookbook_versions(environment, options[:cookbook_versions])
109
+ set_cookbook_versions(environment, cookbook_versions)
110
110
  end
111
111
 
112
112
  if options[:environment_attributes].any?
@@ -61,6 +61,7 @@ module MotherBrain
61
61
  aliases: "--components"
62
62
  method_option :cookbook_versions,
63
63
  type: :hash,
64
+ hidden: true,
64
65
  desc: "The cookbook versions to set on the environment",
65
66
  aliases: "--cookbooks"
66
67
  method_option :environment_attributes,
@@ -84,6 +85,8 @@ module MotherBrain
84
85
  boot_options = Hash.new.merge(options).deep_symbolize_keys
85
86
  manifest = MB::Bootstrap::Manifest.from_file(manifest_file)
86
87
 
88
+ cookbooks_option_deprecated(options)
89
+
87
90
  job = bootstrapper.async_bootstrap(
88
91
  environment.freeze,
89
92
  manifest.freeze,
@@ -103,6 +106,7 @@ module MotherBrain
103
106
  aliases: "--components"
104
107
  method_option :cookbook_versions,
105
108
  type: :hash,
109
+ hidden: true,
106
110
  desc: "The cookbook versions to set on the environment",
107
111
  aliases: "--cookbooks"
108
112
  method_option :environment_attributes,
@@ -129,6 +133,8 @@ module MotherBrain
129
133
  prov_options = Hash.new.merge(options).deep_symbolize_keys
130
134
  manifest = Provisioner::Manifest.from_file(manifest_file)
131
135
 
136
+ cookbooks_option_deprecated(options)
137
+
132
138
  job = provisioner.async_provision(
133
139
  environment.freeze,
134
140
  manifest.freeze,
@@ -170,6 +176,7 @@ module MotherBrain
170
176
  aliases: "--components"
171
177
  method_option :cookbook_versions,
172
178
  type: :hash,
179
+ hide: true,
173
180
  desc: "The cookbook versions to set on the environment",
174
181
  aliases: "--cookbooks"
175
182
  method_option :environment_attributes,
@@ -196,12 +203,7 @@ module MotherBrain
196
203
  define_method(:upgrade) do
197
204
  upgrade_options = Hash.new.merge(options).deep_symbolize_keys
198
205
 
199
- requires_one_of [
200
- :component_versions,
201
- :cookbook_versions,
202
- :environment_attributes,
203
- :environment_attributes_file
204
- ]
206
+ cookbooks_option_deprecated(options)
205
207
 
206
208
  job = upgrade_manager.async_upgrade(
207
209
  environment.freeze,
@@ -220,6 +222,14 @@ module MotherBrain
220
222
  ui.say plugin.metadata.attributes.to_yaml
221
223
  end
222
224
  end
225
+
226
+ no_commands do
227
+ def cookbooks_option_deprecated(options)
228
+ if options[:cookbook_versions]
229
+ ui.deprecated "--cookbooks option is deprecated in favor of loading versions from Berksfile.lock"
230
+ end
231
+ end
232
+ end
223
233
  end
224
234
 
225
235
  klass
data/lib/mb/group.rb CHANGED
@@ -57,8 +57,8 @@ module MotherBrain
57
57
  "#{attribute_escape(key)}:#{value}"
58
58
  end
59
59
 
60
- items += roles.collect { |role| "roles:#{solr_escape(role)}" }
61
- items += recipes.collect { |recipe| "recipes:#{solr_escape(recipe)}" }
60
+ items += roles.collect { |role| "run_list:#{solr_escape('role['+role+']')}" }
61
+ items += recipes.collect { |recipe| "run_list:#{solr_escape('recipe['+recipe+']')}" }
62
62
 
63
63
  items.join(' AND ')
64
64
  end
@@ -50,7 +50,7 @@ module MotherBrain
50
50
  node_failures_count = 0
51
51
  node_failures = Array.new
52
52
 
53
- futures = nodes.map { |node| node_querier.future(:chef_run, node.public_hostname, node_object: node, override_recipes: override_recipes) }
53
+ futures = nodes.map { |node| node_querier.future(:chef_run, node.public_hostname, override_recipes: override_recipes) }
54
54
 
55
55
  futures.each do |future|
56
56
  begin
@@ -125,21 +125,12 @@ module MotherBrain
125
125
  end
126
126
 
127
127
  response = if options[:override_recipes]
128
- node = options[:node_object]
129
- node.reload
130
- old_recipes = node.automatic_attributes.recipes
131
128
  override_recipes = options[:override_recipes]
132
129
 
133
130
  cmd_recipe_syntax = override_recipes.join(',') { |recipe| "recipe[#{recipe}]" }
134
131
  log.info { "Running Chef client with override runlist '#{cmd_recipe_syntax}' on: #{host}" }
135
132
  chef_run_response = chef_connection.node.execute_command(host, "chef-client --override-runlist #{cmd_recipe_syntax}")
136
133
 
137
- # reset the run list
138
- node.reload
139
- log.info { "Resetting node's recipes attribute back to #{old_recipes}" }
140
- node.automatic_attributes.recipes = old_recipes
141
- node.save
142
-
143
134
  chef_run_response
144
135
  else
145
136
  log.info { "Running Chef client on: #{host}" }
data/lib/mb/plugin.rb CHANGED
@@ -4,18 +4,24 @@ module MotherBrain
4
4
  # Create a new plugin instance from the given content
5
5
  #
6
6
  # @param [MB::CookbookMetadata] metadata
7
+ # @param [Hash<String, String>] cookbook_versions
8
+ # The cookbook dependencies which this plugin depends on. Key is
9
+ # the cookbook name and the value is the version of the cookbook.
7
10
  #
8
11
  # @raise [PluginLoadError]
9
12
  #
10
13
  # @yieldreturn [MotherBrain::Plugin]
11
- def load(metadata, &block)
12
- new(metadata, &block).validate!
14
+ def load(metadata, cookbook_versions = {}, &block)
15
+ new(metadata, cookbook_versions, &block).validate!
13
16
  rescue PluginSyntaxError => ex
14
17
  ErrorHandler.wrap(ex)
15
18
  end
16
19
 
17
20
  # Load the contents of a directory into an instance of MB::Plugin
18
21
  #
22
+ # The cookbook dependencies of this plugin will be loaded from the
23
+ # Berksfile.lock if it is found.
24
+ #
19
25
  # @param [#to_s] path
20
26
  # a path to a directory containing a motherbrain plugin file and cookbook
21
27
  # metadata file
@@ -31,8 +37,9 @@ module MotherBrain
31
37
  plugin_filename = File.join(path, PLUGIN_FILENAME)
32
38
  plugin_contents = File.read(plugin_filename)
33
39
  metadata = CookbookMetadata.from_path(path)
40
+ berksfile_lock = Berkshelf::Lockfile.from_path(path)
34
41
 
35
- load(metadata) { eval(plugin_contents, binding, plugin_filename, 1) }
42
+ load(metadata, berksfile_lock.locked_versions) { eval(plugin_contents, binding, plugin_filename, 1) }
36
43
  rescue PluginSyntaxError => ex
37
44
  raise PluginSyntaxError, ErrorHandler.new(ex, file_path: plugin_filename).message
38
45
  end
@@ -58,6 +65,8 @@ module MotherBrain
58
65
  attr_reader :components
59
66
  # @return [Set<MB::Command>]
60
67
  attr_reader :commands
68
+ # @return [Hash<String, String>]
69
+ attr_reader :cookbook_versions
61
70
 
62
71
  def_delegator :metadata, :name
63
72
  def_delegator :metadata, :maintainer
@@ -68,10 +77,14 @@ module MotherBrain
68
77
  def_delegator :metadata, :version
69
78
 
70
79
  # @param [MB::CookbookMetadata] metadata
71
- def initialize(metadata, &block)
72
- @metadata = metadata
73
- @components = Set.new
74
- @commands = Set.new
80
+ # @param [Hash<String, String>] cookbook_versions
81
+ # The cookbook dependencies which this plugin depends on. Key is
82
+ # the cookbook name and the value is the version of the cookbook.
83
+ def initialize(metadata, cookbook_versions = {}, &block)
84
+ @metadata = metadata
85
+ @cookbook_versions = cookbook_versions
86
+ @components = Set.new
87
+ @commands = Set.new
75
88
 
76
89
  if block_given?
77
90
  dsl_eval(&block)
@@ -104,7 +104,7 @@ module MotherBrain
104
104
 
105
105
  # @return [Hash]
106
106
  def cookbook_versions
107
- options[:cookbook_versions] || {}
107
+ options[:cookbook_versions] || plugin.cookbook_versions
108
108
  end
109
109
 
110
110
  # @return [Hash]
data/lib/mb/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module MotherBrain
2
- VERSION = '0.14.4'
2
+ VERSION = '0.14.5'
3
3
  end
data/lib/motherbrain.rb CHANGED
@@ -20,6 +20,7 @@ require 'mb/core_ext'
20
20
  require 'mb/grape_ext'
21
21
  require 'mb/ridley_ext'
22
22
  require 'mb/thor_ext'
23
+ require 'berkshelf'
23
24
 
24
25
  module MotherBrain
25
26
  autoload :API, 'mb/api'
data/motherbrain.gemspec CHANGED
@@ -55,4 +55,5 @@ Gem::Specification.new do |s|
55
55
  s.add_dependency 'buff-platform', '~> 0.1'
56
56
  s.add_dependency 'buff-ruby_engine', '~> 0.1'
57
57
  s.add_dependency 'grape-swagger', '~> 0.6.0'
58
+ s.add_dependency 'berkshelf', '~> 3.0.0.beta7'
58
59
  end
@@ -0,0 +1,3 @@
1
+ GRAPH
2
+ cookbook1 (2.0.1)
3
+ cookbook2 (1.0.13)
data/spec/spec_helper.rb CHANGED
@@ -13,6 +13,7 @@ require 'motherbrain'
13
13
  require 'chef_zero/server'
14
14
 
15
15
  def setup_rspec
16
+ require File.expand_path('../../spec/support/berkshelf.rb', __FILE__)
16
17
  Dir[File.join(File.expand_path("../../spec/support/**/*.rb", __FILE__))].each { |f| require f }
17
18
 
18
19
  RSpec.configure do |config|
@@ -35,4 +35,21 @@ describe MB::Berkshelf do
35
35
  subject.should be_a(Pathname)
36
36
  end
37
37
  end
38
+
39
+ describe MB::Berkshelf::Lockfile do
40
+ describe "#locked_versions" do
41
+
42
+ let(:plugin_path) { '/foo' }
43
+ subject { MB::Berkshelf::Lockfile.from_path(plugin_path) }
44
+
45
+ context "when there is no lockfile present" do
46
+ its(:locked_versions) { should == {} }
47
+ end
48
+
49
+ context "when there is a lockfile present" do
50
+ let(:plugin_path) { fixtures_path.join('myface-0.1.0') }
51
+ its(:locked_versions) { should == {'cookbook1' => '2.0.1', 'cookbook2' => '1.0.13'}}
52
+ end
53
+ end
54
+ end
38
55
  end
@@ -8,8 +8,10 @@ describe MB::Bootstrap::Manager do
8
8
  MB::CookbookMetadata.from_file(fixtures_path.join('cb_metadata.rb'))
9
9
  }
10
10
 
11
+ let(:cookbook_versions) { {} }
12
+
11
13
  let(:plugin) {
12
- MB::Plugin.new(cookbook_metadata) do
14
+ MB::Plugin.new(cookbook_metadata, cookbook_versions) do
13
15
  component "activemq" do
14
16
  group "master"
15
17
  group "slave"
@@ -132,6 +134,15 @@ describe MB::Bootstrap::Manager do
132
134
  end
133
135
  end
134
136
 
137
+ context "when the plugin has cookbook version dependencies set" do
138
+ let(:cookbook_versions) { {'cookbook1' => '1.2.3', 'cookbook2' => '4.5.6'} }
139
+
140
+ it "should set the cookbook versions on the environment" do
141
+ manager.should_receive(:set_cookbook_versions).with(environment, cookbook_versions)
142
+ run
143
+ end
144
+ end
145
+
135
146
  context "when :environment_attributes_file is passed as an option" do
136
147
  let(:filepath) { double }
137
148
 
@@ -189,7 +189,7 @@ describe MB::Group do
189
189
  end
190
190
 
191
191
  it "returns them escaped and joined together by AND" do
192
- expect(subject).to eql("chef_environment:#{environment} AND recipes:pvpnet\\:\\:default AND recipes:pvpnet\\:\\:database")
192
+ expect(subject).to eql("chef_environment:#{environment} AND run_list:recipe\\[pvpnet\\:\\:default\\] AND run_list:recipe\\[pvpnet\\:\\:database\\]")
193
193
  end
194
194
  end
195
195
 
@@ -201,7 +201,7 @@ describe MB::Group do
201
201
  end
202
202
 
203
203
  it "does not escape the dash" do
204
- expect(subject).to eql("chef_environment:#{environment} AND recipes:build-essential")
204
+ expect(subject).to eql("chef_environment:#{environment} AND run_list:recipe\\[build-essential\\]")
205
205
  end
206
206
  end
207
207
 
@@ -214,7 +214,7 @@ describe MB::Group do
214
214
  end
215
215
 
216
216
  it "returns them escaped and joined together by AND" do
217
- expect(subject).to eql("chef_environment:#{environment} AND roles:app_server AND roles:database_server")
217
+ expect(subject).to eql("chef_environment:#{environment} AND run_list:role\\[app_server\\] AND run_list:role\\[database_server\\]")
218
218
  end
219
219
  end
220
220
  end
@@ -107,6 +107,10 @@ describe MB::Plugin do
107
107
  it "returns a MB::Plugin from the given directory" do
108
108
  subject.should be_a(MB::Plugin)
109
109
  end
110
+
111
+ it "sets the cookbook_versions from the Berksfile.lock" do
112
+ subject.cookbook_versions.should == {'cookbook1' => '2.0.1', 'cookbook2' => '1.0.13'}
113
+ end
110
114
  end
111
115
  end
112
116
 
@@ -15,7 +15,8 @@ describe MB::Upgrade::Worker do
15
15
  let(:job) { job_double }
16
16
  let(:options) { Hash.new }
17
17
  let(:nodes) { %w[node1 node2 node3] }
18
- let(:plugin) { double MB::Plugin, name: plugin_name }
18
+ let(:locked_versions) { {} }
19
+ let(:plugin) { double MB::Plugin, name: plugin_name, cookbook_versions: locked_versions }
19
20
  let(:plugin_name) { "plugin_name" }
20
21
 
21
22
  before do
@@ -61,6 +62,15 @@ describe MB::Upgrade::Worker do
61
62
  end
62
63
  end
63
64
 
65
+ context "when cookbooks are found in the Berksfile.lock" do
66
+ let(:locked_versions) { {'foo' => '1.2.3', 'bar' => '4.5.6'} }
67
+ it "updates the cookbook versions from the lockfile" do
68
+ worker.should_receive(:set_cookbook_versions).with(environment_name, locked_versions)
69
+ run
70
+ end
71
+
72
+ end
73
+
64
74
  context "when only cookbook_versions is passed as an option" do
65
75
  before do
66
76
  options[:cookbook_versions] = cookbook_versions
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: motherbrain
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.4
4
+ version: 0.14.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jamie Winsor
@@ -15,7 +15,7 @@ authors:
15
15
  autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
- date: 2014-03-20 00:00:00.000000000 Z
18
+ date: 2014-03-25 00:00:00.000000000 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: celluloid
@@ -283,6 +283,20 @@ dependencies:
283
283
  - - ~>
284
284
  - !ruby/object:Gem::Version
285
285
  version: 0.6.0
286
+ - !ruby/object:Gem::Dependency
287
+ name: berkshelf
288
+ requirement: !ruby/object:Gem::Requirement
289
+ requirements:
290
+ - - ~>
291
+ - !ruby/object:Gem::Version
292
+ version: 3.0.0.beta7
293
+ type: :runtime
294
+ prerelease: false
295
+ version_requirements: !ruby/object:Gem::Requirement
296
+ requirements:
297
+ - - ~>
298
+ - !ruby/object:Gem::Version
299
+ version: 3.0.0.beta7
286
300
  description: An orchestrator for Chef
287
301
  email:
288
302
  - jamie@vialstudios.com
@@ -459,6 +473,7 @@ files:
459
473
  - spec/fixtures/cb_metadata.rb
460
474
  - spec/fixtures/fake_id_rsa
461
475
  - spec/fixtures/fake_key.pem
476
+ - spec/fixtures/myface-0.1.0/Berksfile.lock
462
477
  - spec/fixtures/myface-0.1.0/metadata.rb
463
478
  - spec/fixtures/myface-0.1.0/motherbrain.rb
464
479
  - spec/fixtures/test_env.json
@@ -607,6 +622,7 @@ test_files:
607
622
  - spec/fixtures/cb_metadata.rb
608
623
  - spec/fixtures/fake_id_rsa
609
624
  - spec/fixtures/fake_key.pem
625
+ - spec/fixtures/myface-0.1.0/Berksfile.lock
610
626
  - spec/fixtures/myface-0.1.0/metadata.rb
611
627
  - spec/fixtures/myface-0.1.0/motherbrain.rb
612
628
  - spec/fixtures/test_env.json