motherbrain 1.1.3 → 1.2.0

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: f62e98f5b68edf8d5b1fe136be7d161e34a33b40
4
- data.tar.gz: 57125dfcf9d5d7def16f5fa375c9ea74b23b5278
3
+ metadata.gz: 92e848a7145f24eb7bcaee3193cb4445382e4dc5
4
+ data.tar.gz: f348b5cd5442d64ec7ecf4b575349fee037349cf
5
5
  SHA512:
6
- metadata.gz: ae54535d3adb4a56fd180373fabc0d56ad7fd8f1081d430da14e15fc0551d7066a4fa91259ef1914e6809709c2eeb0ff4dfb9cb83dbfd4185d43c85bf2400fac
7
- data.tar.gz: a5745aa04d56ce0ad5aa419fa285045e83f36662a741029ef8dc03f6b3f6a050bfe590772f9e67b2dd257ccea0edec6021fccc9e36e383ed84e6c301e9c407cc
6
+ metadata.gz: 30ba05db9263dc38a8a9d57bdb3351025e69ee13e5683e97e859b6ebe8f88abaa8e7afe49495f3b7a174f2e148f66eb3a0cb315739d852c12e1a3b264e7a2e9e
7
+ data.tar.gz: 8d2cf420dcfa7bede15b895f0b26f8b0a3d817a7e5473cc0449faae9c239b59f32b2c45821466e458af8ab4ccd7ed681d7ad269492c8dbede896922e01135a21
data/.gitignore CHANGED
@@ -25,3 +25,4 @@ man/mb.1.ronn
25
25
  *~
26
26
  \#*
27
27
  .DS_store
28
+ .ruby-version
@@ -1,3 +1,11 @@
1
+ # 1.2.0
2
+
3
+ * [#701](https://github.com/RiotGames/motherbrain/pull/701) Pass OS hints through to ridley-connectors for smarter connector picking
4
+ * [#700](https://github.com/RiotGames/motherbrain/pull/700) Fix for rspec-guard syntax
5
+ * [#699](https://github.com/RiotGames/motherbrain/pull/699) Use the currently logged in user as a default in SSH / WinRM config
6
+ * [#698](https://github.com/RiotGames/motherbrain/pull/698) Removing the .ruby-version file because it makes dev a pain
7
+ * [#695](https://github.com/RiotGames/motherbrain/pull/695) Add a better lock on ridley-connectors
8
+
1
9
  # 1.1.3
2
10
 
3
11
  * [#694](https://github.com/RiotGames/motherbrain/pull/694) Upgrade to reel 0.5.0
data/Gemfile CHANGED
@@ -40,7 +40,6 @@ group :test do
40
40
  gem 'guard-cucumber'
41
41
  gem 'guard-rspec'
42
42
  gem 'guard-spork'
43
- gem 'guard-yard'
44
43
 
45
44
  require 'rbconfig'
46
45
 
data/Guardfile CHANGED
@@ -1,18 +1,12 @@
1
1
  notification :off
2
2
 
3
- guard 'spork' do
3
+ guard :spork do
4
4
  watch('Gemfile')
5
5
  watch('spec/spec_helper.rb') { :rspec }
6
6
  watch(%r{^spec/support/.+\.rb$}) { :rspec }
7
7
  end
8
8
 
9
- guard 'yard', stdout: '/dev/null', stderr: '/dev/null' do
10
- watch(%r{app/.+\.rb})
11
- watch(%r{lib/.+\.rb})
12
- watch(%r{ext/.+\.c})
13
- end
14
-
15
- guard 'rspec', cli: "--color --drb --format Fuubar", all_on_start: false, all_after_pass: false do
9
+ guard :rspec, cmd: "bundle exec rspec --color --drb --format Fuubar", all_on_start: false, all_after_pass: false do
16
10
  watch(%r{^spec/unit/.+_spec\.rb$})
17
11
  watch(%r{^spec/acceptance/.+_spec\.rb$})
18
12
 
@@ -21,7 +15,7 @@ guard 'rspec', cli: "--color --drb --format Fuubar", all_on_start: false, all_af
21
15
  watch('spec/spec_helper.rb') { "spec" }
22
16
  end
23
17
 
24
- guard 'cucumber', cli: "--drb --require features --format pretty", all_on_start: false, all_after_pass: false do
18
+ guard :cucumber, cli: "--drb --require features --format pretty", all_on_start: false, all_after_pass: false do
25
19
  watch(%r{^features/.+\.feature$})
26
20
  watch(%r{^features/support/.+$}) { 'features' }
27
21
  watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
@@ -87,6 +87,7 @@ module MotherBrain
87
87
  type: String
88
88
 
89
89
  attribute 'ssh.user',
90
+ default: ENV['USER'],
90
91
  type: String
91
92
 
92
93
  attribute 'ssh.password',
@@ -108,6 +109,7 @@ module MotherBrain
108
109
  type: String
109
110
 
110
111
  attribute 'winrm.user',
112
+ default: ENV['USER'],
111
113
  type: String
112
114
 
113
115
  attribute 'winrm.password',
@@ -81,7 +81,7 @@ module MotherBrain
81
81
 
82
82
  job.set_status("Performing a chef client run on #{nodes.length} nodes")
83
83
  nodes.collect do |node|
84
- node_querier.future(:chef_run, node.public_hostname)
84
+ node_querier.future(:chef_run, node.public_hostname, connector: node.chef_attributes.os)
85
85
  end.each do |future|
86
86
  begin
87
87
  response = future.value
@@ -216,7 +216,7 @@ module MotherBrain
216
216
  #
217
217
  # @return [Array(Ridley::NodeObject)]
218
218
  def nodes_for_environment(name)
219
- ridley.partial_search(:node, "chef_environment:#{name}", ["fqdn", "cloud.public_hostname", "name"])
219
+ ridley.partial_search(:node, "chef_environment:#{name}", ["fqdn", "cloud.public_hostname", "name", "os"])
220
220
  end
221
221
 
222
222
  private
@@ -40,7 +40,7 @@ module MotherBrain
40
40
  #
41
41
  # @return [Array<Ridley::Node>]
42
42
  def nodes(environment)
43
- Application.ridley.partial_search(:node, search_query(environment), [ "public_ipv4", "public_hostname" ])
43
+ Application.ridley.partial_search(:node, search_query(environment), [ "public_ipv4", "public_hostname", "os" ])
44
44
  end
45
45
 
46
46
  # Returns an escape search query for Solr from the roles, rescipes, and chef_attributes
@@ -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, override_recipes: override_recipes) }
53
+ futures = nodes.map { |node| node_querier.future(:chef_run, node.public_hostname, override_recipes: override_recipes, connector: connector_for_os(node.chef_attributes.os)) }
54
54
 
55
55
  futures.each do |future|
56
56
  begin
@@ -85,6 +85,8 @@ module MotherBrain
85
85
  # timeout value for SSH bootstrap
86
86
  # @option options [Boolean] :sudo (true)
87
87
  # bootstrap with sudo
88
+ # @option options [String] :connector
89
+ # a connector type for the chef connection to prefer
88
90
  #
89
91
  # @return [String, nil]
90
92
  def node_name(host, options = {})
@@ -112,6 +114,8 @@ module MotherBrain
112
114
  # a recipe that will override the nodes current run list
113
115
  # @option options [Ridley::NodeObject] :node
114
116
  # the actual node object
117
+ # @option options [String] :connector
118
+ # a connector type for the chef connection to prefer
115
119
  #
116
120
  # @raise [RemoteCommandError] if an execution error occurs in the remote command
117
121
  # @raise [RemoteCommandError] if given a blank or nil hostname
@@ -129,16 +133,16 @@ module MotherBrain
129
133
 
130
134
  cmd_recipe_syntax = override_recipes.join(',') { |recipe| "recipe[#{recipe}]" }
131
135
  log.info { "Running Chef client with override runlist '#{cmd_recipe_syntax}' on: #{host}" }
132
- chef_run_response = safe_remote(host) { chef_connection.node.execute_command(host, "chef-client --override-runlist #{cmd_recipe_syntax}") }
136
+ chef_run_response = safe_remote(host) { chef_connection.node.execute_command(host, "chef-client --override-runlist #{cmd_recipe_syntax}", connector: options[:connector]) }
133
137
 
134
138
  chef_run_response
135
139
  else
136
140
  log.info { "Running Chef client on: #{host}" }
137
- safe_remote(host) { chef_connection.node.chef_run(host) }
141
+ safe_remote(host) { chef_connection.node.chef_run(host, connector: options[:connector]) }
138
142
  end
139
143
 
140
144
  if response.error?
141
- log.info { "Failed Chef client run on: #{host}" }
145
+ log.info { "Failed Chef client run on: #{host} - #{response.stderr.chomp}" }
142
146
  abort RemoteCommandError.new(response.stderr.chomp, host)
143
147
  end
144
148
 
@@ -166,6 +170,8 @@ module MotherBrain
166
170
  # timeout value for SSH bootstrap
167
171
  # @option options [Boolean] :sudo
168
172
  # bootstrap with sudo
173
+ # @option options [String] :connector
174
+ # a connector type for the chef connection to prefer
169
175
  #
170
176
  # @raise [RemoteFileCopyError]
171
177
  #
@@ -181,7 +187,7 @@ module MotherBrain
181
187
  abort RemoteCommandError.new("cannot put_secret without a hostname or ipaddress")
182
188
  end
183
189
 
184
- response = safe_remote(host) { chef_connection.node.put_secret(host) }
190
+ response = safe_remote(host) { chef_connection.node.put_secret(host, connector: options[:connector]) }
185
191
 
186
192
  if response.error?
187
193
  log.info { "Failed to put secret file on: #{host}" }
@@ -197,15 +203,17 @@ module MotherBrain
197
203
  #
198
204
  # @param [String] host
199
205
  # @param [String] command
206
+ # @option options [String] :connector
207
+ # a connector type for the chef connection to prefer
200
208
  #
201
209
  # @return [Ridley::HostConnection::Response]
202
- def execute_command(host, command)
210
+ def execute_command(host, command, options = {})
203
211
 
204
212
  unless host.present?
205
213
  abort RemoteCommandError.new("cannot execute command without a hostname or ipaddress")
206
214
  end
207
215
 
208
- response = safe_remote(host) { chef_connection.node.execute_command(host, command) }
216
+ response = safe_remote(host) { chef_connection.node.execute_command(host, command, connector: options[:connector]) }
209
217
 
210
218
  if response.error?
211
219
  log.info { "Failed to execute command on: #{host}" }
@@ -313,6 +321,10 @@ module MotherBrain
313
321
  # skip removal of the Chef package and the contents of the installation
314
322
  # directory. Setting this to true will only remove any data and configurations
315
323
  # generated by running Chef client.
324
+ # @option options [String] :connector
325
+ # a connector type for the chef connection to prefer
326
+ #
327
+ # @return [MB::JobTicket]
316
328
  def purge(job, host, options = {})
317
329
  options = options.reverse_merge(skip_chef: false)
318
330
  futures = Array.new
@@ -328,7 +340,7 @@ module MotherBrain
328
340
  end
329
341
 
330
342
  job.set_status("Cleaning up the host's file system.")
331
- futures << chef_connection.node.future(:uninstall_chef, host, options.slice(:skip_chef))
343
+ futures << chef_connection.node.future(:uninstall_chef, host, options.slice(:skip_chef, :connector))
332
344
 
333
345
  begin
334
346
  safe_remote(host) { futures.map(&:value) }
@@ -471,6 +483,24 @@ module MotherBrain
471
483
  log.debug { "Node Querier stopping..." }
472
484
  end
473
485
 
486
+ # Returns a String representing the best connector
487
+ # type to use when communicating with a given node
488
+ #
489
+ # @param os [String]
490
+ # the operating system
491
+ #
492
+ # @return [String]
493
+ def connector_for_os(os)
494
+ case os
495
+ when "windows"
496
+ Ridley::HostCommander::DEFAULT_WINDOWS_CONNECTOR
497
+ when "linux"
498
+ Ridley::HostCommander::DEFAULT_LINUX_CONNECTOR
499
+ else
500
+ nil
501
+ end
502
+ end
503
+
474
504
  # Run a Ruby script on the target host and return the result of STDOUT. Only scripts
475
505
  # that are located in the Mother Brain scripts directory can be used and they should
476
506
  # be identified just by their filename minus the extension
@@ -493,6 +523,8 @@ module MotherBrain
493
523
  # timeout value for SSH bootstrap
494
524
  # @option options [Boolean] :sudo (true)
495
525
  # bootstrap with sudo
526
+ # @option options [String] :connector
527
+ # a connector type for the chef connection to prefer
496
528
  #
497
529
  # @raise [RemoteScriptError] if there was an error in execution
498
530
  # @raise [RuntimeError] if an unknown response is returned from Ridley
@@ -512,7 +544,7 @@ module MotherBrain
512
544
  abort RemoteCommandError.new("cannot execute a ruby_script without a hostname or ipaddress")
513
545
  end
514
546
 
515
- response = safe_remote(host) { chef_connection.node.ruby_script(host, command_lines) }
547
+ response = safe_remote(host) { chef_connection.node.ruby_script(host, command_lines, connector: options[:connector]) }
516
548
 
517
549
  if response.error?
518
550
  raise RemoteScriptError.new(response.stderr.chomp)
@@ -1,3 +1,3 @@
1
1
  module MotherBrain
2
- VERSION = '1.1.3'
2
+ VERSION = '1.2.0'
3
3
  end
@@ -44,7 +44,7 @@ Gem::Specification.new do |s|
44
44
  s.add_dependency 'net-ssh'
45
45
  s.add_dependency 'net-sftp'
46
46
  s.add_dependency 'solve', '~> 1.1'
47
- s.add_dependency 'ridley-connectors', '~> 2.0'
47
+ s.add_dependency 'ridley-connectors', '~> 2.1'
48
48
  s.add_dependency 'thor', '~> 0.18.0'
49
49
  s.add_dependency 'faraday', '~> 0.9'
50
50
  s.add_dependency 'multi_json'
@@ -33,14 +33,21 @@ describe MB::Config do
33
33
 
34
34
  subject do
35
35
  MB::Config.new.tap do |o|
36
- o.chef.api_url = "https://api.opscode.com/organizations/vialstudio"
36
+ o.chef.api_url = "https://api.opscode.com/organizations/vialstudio"
37
37
  o.chef.api_client = "reset"
38
- o.chef.api_key = "/Users/reset/.chef/reset.pem"
39
- o.ssh.user = "root"
40
- o.ssh.password = "something"
38
+ o.chef.api_key = "/Users/reset/.chef/reset.pem"
39
+ o.ssh.password = "something"
41
40
  end
42
41
  end
43
42
 
43
+ it "uses the currently logged in user as the default ssh user" do
44
+ expect(subject.ssh.user).to eql(ENV['USER'])
45
+ end
46
+
47
+ it "uses the currently logged in user as the default winrm user" do
48
+ expect(subject.winrm.user).to eql(ENV['USER'])
49
+ end
50
+
44
51
  describe "#log.level" do
45
52
  it "converts the string 'info' to 'INFO'" do
46
53
  subject.log.level = 'info'
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: 1.1.3
4
+ version: 1.2.0
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-04-18 00:00:00.000000000 Z
18
+ date: 2014-04-29 00:00:00.000000000 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: celluloid
@@ -149,14 +149,14 @@ dependencies:
149
149
  requirements:
150
150
  - - ~>
151
151
  - !ruby/object:Gem::Version
152
- version: '2.0'
152
+ version: '2.1'
153
153
  type: :runtime
154
154
  prerelease: false
155
155
  version_requirements: !ruby/object:Gem::Requirement
156
156
  requirements:
157
157
  - - ~>
158
158
  - !ruby/object:Gem::Version
159
- version: '2.0'
159
+ version: '2.1'
160
160
  - !ruby/object:Gem::Dependency
161
161
  name: thor
162
162
  requirement: !ruby/object:Gem::Requirement
@@ -344,7 +344,6 @@ extensions: []
344
344
  extra_rdoc_files: []
345
345
  files:
346
346
  - .gitignore
347
- - .ruby-version
348
347
  - .travis.yml
349
348
  - CHANGELOG.md
350
349
  - COMMANDS.md
@@ -1 +0,0 @@
1
- 2.0.0-p353