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 +4 -4
- data/CHANGELOG.md +10 -0
- data/Gemfile +1 -1
- data/lib/mb/berkshelf.rb +31 -0
- data/lib/mb/bootstrap/manager.rb +3 -3
- data/lib/mb/cli/sub_command/plugin.rb +16 -6
- data/lib/mb/group.rb +2 -2
- data/lib/mb/node_querier.rb +1 -10
- data/lib/mb/plugin.rb +20 -7
- data/lib/mb/upgrade/worker.rb +1 -1
- data/lib/mb/version.rb +1 -1
- data/lib/motherbrain.rb +1 -0
- data/motherbrain.gemspec +1 -0
- data/spec/fixtures/myface-0.1.0/Berksfile.lock +3 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/unit/mb/berkshelf_spec.rb +17 -0
- data/spec/unit/mb/bootstrap/manager_spec.rb +12 -1
- data/spec/unit/mb/group_spec.rb +3 -3
- data/spec/unit/mb/plugin_spec.rb +4 -0
- data/spec/unit/mb/upgrade/worker_spec.rb +11 -1
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 45f24209faef88c327c3979ebdf59cdc961bf530
|
4
|
+
data.tar.gz: 49f3bbdb3c81b052aa3a1eddfdc1256427818653
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e50ad349193026c2bd4c221e6ec3e9a78729c6dc1304bfe130a6f0be20d2011d3f480f708926a3cb73410790e833b98b9da2aec831d881948ab1ad3d23273145
|
7
|
+
data.tar.gz: e32e2999bbfb6157237bfffd0a3fc1320f0bd1ce4164ee35960fd6c0b3046ceb77b490d538f31e53aa2d5fbf5638227d297fa98a46d2b803f47f4179d14ec466
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
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
|
data/lib/mb/bootstrap/manager.rb
CHANGED
@@ -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
|
-
|
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,
|
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
|
-
|
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| "
|
61
|
-
items += recipes.collect { |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
|
data/lib/mb/node_querier.rb
CHANGED
@@ -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,
|
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
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
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)
|
data/lib/mb/upgrade/worker.rb
CHANGED
data/lib/mb/version.rb
CHANGED
data/lib/motherbrain.rb
CHANGED
data/motherbrain.gemspec
CHANGED
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
|
|
data/spec/unit/mb/group_spec.rb
CHANGED
@@ -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
|
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
|
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
|
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
|
data/spec/unit/mb/plugin_spec.rb
CHANGED
@@ -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(:
|
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
|
+
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-
|
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
|