motherbrain 0.14.4 → 0.14.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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