knife-solo 0.2.0 → 0.3.0.pre1

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.
@@ -1,3 +1,5 @@
1
+ # 0.3.0: _In progress_
2
+
1
3
  # 0.2.0: February 12, 2013
2
4
 
3
5
  ## Changes and new features
@@ -16,6 +18,7 @@
16
18
  * Drop support for Debian 5.0 Lenny (#172)
17
19
  * Integration tests for Debian 6 and 7 (74c6ed1 - f299a6)
18
20
  * Travis tests for both Chef 10 and 11 (#183)
21
+ * Remove solo.rb and transfer cookbooks to user-owned path (#1, #86, #125, #128, #177). See https://github.com/matschaffer/knife-solo/wiki/Upgrading-to-0.2.0
19
22
 
20
23
  ## Fixes
21
24
 
@@ -2,13 +2,11 @@ require 'chef/knife'
2
2
  require 'chef/knife/solo_cook'
3
3
  require 'chef/knife/solo_prepare'
4
4
 
5
- require 'knife-solo/kitchen_command'
6
5
  require 'knife-solo/ssh_command'
7
6
 
8
7
  class Chef
9
8
  class Knife
10
9
  class SoloBootstrap < Knife
11
- include KnifeSolo::KitchenCommand
12
10
  include KnifeSolo::SshCommand
13
11
 
14
12
  deps do
@@ -36,7 +34,6 @@ class Chef
36
34
 
37
35
  def validate!
38
36
  validate_ssh_options!
39
- validate_kitchen!
40
37
  end
41
38
 
42
39
  def command_with_same_args(klass)
@@ -1,24 +1,24 @@
1
1
  require 'chef/knife'
2
+
2
3
  require 'knife-solo/ssh_command'
3
- require 'knife-solo/kitchen_command'
4
+ require 'knife-solo/config'
4
5
 
5
6
  class Chef
6
7
  class Knife
7
8
  class SoloClean < Knife
8
9
  include KnifeSolo::SshCommand
9
- include KnifeSolo::KitchenCommand
10
10
 
11
11
  banner "knife solo clean [USER@]HOSTNAME"
12
12
 
13
13
  def run
14
+ @solo_config = KnifeSolo::Config.new
14
15
  validate!
15
- Chef::Config.from_file('solo.rb')
16
- run_command "rm -rf #{Chef::Config.file_cache_path}"
16
+ run_command "rm -rf #{@solo_config.chef_path}"
17
17
  end
18
18
 
19
19
  def validate!
20
20
  validate_ssh_options!
21
- validate_kitchen!
21
+ @solo_config.validate!
22
22
  end
23
23
  end
24
24
  end
@@ -1,9 +1,10 @@
1
1
  require 'chef/knife'
2
2
 
3
+ require 'knife-solo'
3
4
  require 'knife-solo/ssh_command'
4
- require 'knife-solo/kitchen_command'
5
5
  require 'knife-solo/node_config_command'
6
6
  require 'knife-solo/tools'
7
+ require 'knife-solo/config'
7
8
 
8
9
  class Chef
9
10
  class Knife
@@ -13,7 +14,6 @@ class Chef
13
14
  CHEF_VERSION_CONSTRAINT = ">=0.10.4" unless defined? CHEF_VERSION_CONSTRAINT
14
15
 
15
16
  include KnifeSolo::SshCommand
16
- include KnifeSolo::KitchenCommand
17
17
  include KnifeSolo::NodeConfigCommand
18
18
  include KnifeSolo::Tools
19
19
 
@@ -52,6 +52,8 @@ class Chef
52
52
  :description => 'Enable whyrun mode'
53
53
 
54
54
  def run
55
+ @solo_config = KnifeSolo::Config.new
56
+
55
57
  time('Run') do
56
58
  if config[:skip_chef_check]
57
59
  ui.warn '`--skip-chef-check` is deprecated, please use `--no-chef-check`.'
@@ -59,53 +61,35 @@ class Chef
59
61
  end
60
62
 
61
63
  validate!
62
- Chef::Config.from_file('solo.rb')
63
64
  check_chef_version if config[:chef_check]
64
65
  generate_node_config
65
66
  librarian_install if config[:librarian]
66
67
  rsync_kitchen
67
68
  add_patches
69
+ add_solo_config unless using_custom_solorb?
68
70
  cook unless config[:sync_only]
69
71
  end
70
72
  end
71
73
 
74
+ def_delegators :@solo_config,
75
+ :chef_path,
76
+ :using_custom_solorb?,
77
+ :patch_path
78
+
72
79
  def validate!
73
80
  validate_ssh_options!
74
- validate_kitchen!
75
- end
76
-
77
- def chef_path
78
- Chef::Config.file_cache_path
81
+ @solo_config.validate!
79
82
  end
80
83
 
81
84
  def chefignore
82
85
  @chefignore ||= ::Chef::Cookbook::Chefignore.new("./")
83
86
  end
84
87
 
85
- # cygwin rsync path must be adjusted to work
86
- def adjust_rsync_path(path)
87
- path.gsub(/^(\w):/) { "/cygdrive/#{$1}" }
88
- end
89
-
90
- def adjust_rsync_path_on_node(path)
91
- return path unless windows_node?
92
- adjust_rsync_path(path)
93
- end
94
-
95
- def adjust_rsync_path_on_client(path)
96
- return path unless windows_client?
97
- adjust_rsync_path(path)
98
- end
99
-
100
88
  # see http://stackoverflow.com/questions/5798807/rsync-permission-denied-created-directories-have-no-permissions
101
89
  def rsync_permissions
102
90
  '--chmod=ugo=rwX' if windows_client?
103
91
  end
104
92
 
105
- def patch_path
106
- Array(Chef::Config.cookbook_path).first + "/chef_solo_patches/libraries"
107
- end
108
-
109
93
  def rsync_excludes
110
94
  (%w{revision-deploys tmp '.*'} + chefignore.ignores).uniq
111
95
  end
@@ -149,8 +133,12 @@ class Chef
149
133
  end
150
134
  end
151
135
 
136
+ def add_solo_config
137
+ rsync(KnifeSolo.resource('solo.rb'), chef_path)
138
+ end
139
+
152
140
  def rsync(source_path, target_path, extra_opts = '')
153
- cmd = %Q{rsync -rl #{rsync_permissions} --rsh="ssh #{ssh_args}" #{extra_opts} #{rsync_excludes.collect{ |ignore| "--exclude #{ignore} " }.join} #{adjust_rsync_path_on_client(source_path)} :#{adjust_rsync_path_on_node(target_path)}}
141
+ cmd = %Q|rsync -rl #{rsync_permissions} --rsh="ssh #{ssh_args}" #{extra_opts} #{rsync_excludes.collect{ |ignore| "--exclude #{ignore} " }.join} #{source_path} :#{target_path}|
154
142
  ui.msg cmd if debug?
155
143
  system! cmd
156
144
  end
@@ -26,7 +26,6 @@ class Chef
26
26
  create_kitchen
27
27
  create_cupboards %w[nodes roles data_bags site-cookbooks cookbooks]
28
28
  librarian_init if config[:librarian]
29
- create_solo_config
30
29
  end
31
30
 
32
31
  def validate!
@@ -51,22 +50,6 @@ class Chef
51
50
  mkdir @base unless @base == '.'
52
51
  end
53
52
 
54
- def create_solo_config
55
- solo_file = File.join(@base, 'solo.rb')
56
- return if File.exist? solo_file
57
-
58
- File.open(solo_file, 'w') do |f|
59
- f << <<-RUBY.gsub(/^ {12}/, '')
60
- file_cache_path "/tmp/chef-solo"
61
- data_bag_path "/tmp/chef-solo/data_bags"
62
- encrypted_data_bag_secret "/tmp/chef-solo/data_bag_key"
63
- cookbook_path [ "/tmp/chef-solo/site-cookbooks",
64
- "/tmp/chef-solo/cookbooks" ]
65
- role_path "/tmp/chef-solo/roles"
66
- RUBY
67
- end
68
- end
69
-
70
53
  def librarian_init
71
54
  cheffile = File.join(@base, 'Cheffile')
72
55
  unless File.exist?(cheffile)
@@ -1,6 +1,5 @@
1
1
  require 'chef/knife'
2
2
  require 'knife-solo/ssh_command'
3
- require 'knife-solo/kitchen_command'
4
3
  require 'knife-solo/node_config_command'
5
4
 
6
5
  class Chef
@@ -9,7 +8,6 @@ class Chef
9
8
  # Copyright 2010, 2011, Miquel Torres <tobami@googlemail.com>
10
9
  class SoloPrepare < Knife
11
10
  include KnifeSolo::SshCommand
12
- include KnifeSolo::KitchenCommand
13
11
  include KnifeSolo::NodeConfigCommand
14
12
 
15
13
  deps do
@@ -44,7 +42,6 @@ class Chef
44
42
 
45
43
  def validate!
46
44
  validate_ssh_options!
47
- validate_kitchen!
48
45
  end
49
46
 
50
47
  def bootstrap
@@ -1 +1,7 @@
1
1
  require 'knife-solo/info'
2
+
3
+ module KnifeSolo
4
+ def self.resource(name)
5
+ Pathname.new(__FILE__).dirname.join('knife-solo/resources', name)
6
+ end
7
+ end
@@ -0,0 +1,39 @@
1
+ require 'chef/config'
2
+
3
+ module KnifeSolo
4
+ # Encapsulates some logic for checking and extracting
5
+ # path configuration from the structure of the
6
+ # current kitchen
7
+ class Config
8
+ def solo_path
9
+ Chef::Config.knife[:solo_path]
10
+ end
11
+
12
+ def chef_path
13
+ solo_path || './chef-solo'
14
+ end
15
+
16
+ def cookbook_path
17
+ if using_custom_solorb?
18
+ Chef::Config.from_file('solo.rb')
19
+ Array(Chef::Config.cookbook_path).first
20
+ else
21
+ chef_path + '/cookbooks'
22
+ end
23
+ end
24
+
25
+ def patch_path
26
+ cookbook_path + "/chef_solo_patches/libraries"
27
+ end
28
+
29
+ def using_custom_solorb?
30
+ File.exist?('solo.rb')
31
+ end
32
+
33
+ def validate!
34
+ raise Error, "You have a solo.rb file, but knife[:solo_path] is not set. You probably need to delete solo.rb unless you've customized it. See https://github.com/matschaffer/knife-solo/wiki/Upgrading-to-0.3.0 for more information." if using_custom_solorb? && solo_path.nil?
35
+ end
36
+
37
+ class Error < StandardError; end
38
+ end
39
+ end
@@ -1,6 +1,6 @@
1
1
  module KnifeSolo
2
2
  def self.version
3
- '0.2.0'
3
+ '0.3.0.pre1'
4
4
  end
5
5
 
6
6
  def self.post_install_message
@@ -0,0 +1,6 @@
1
+ base = File.expand_path('..', __FILE__)
2
+
3
+ data_bag_path base + '/data_bags'
4
+ encrypted_data_bag_secret base + '/data_bag_key'
5
+ role_path base + '/roles'
6
+ cookbook_path [ base + '/site-cookbooks', base + '/cookbooks' ]
@@ -0,0 +1,13 @@
1
+ module CachePathUsage
2
+ def setup
3
+ super
4
+ FileUtils.cp_r $base_dir.join('support', 'cache_using_cookbook'), 'cookbooks/cache_using_cookbook'
5
+ end
6
+
7
+ def test_changing_a_cached_directory_between_cooks
8
+ write_nodefile(run_count: 1, run_list: ["cache_using_cookbook"])
9
+ assert_subcommand "cook"
10
+ write_nodefile(run_count: 2, run_list: ["cache_using_cookbook"])
11
+ assert_subcommand "cook"
12
+ end
13
+ end
@@ -12,4 +12,5 @@ class Ubuntu12_04Test < IntegrationTest
12
12
  include EmptyCook
13
13
  include Apache2Cook
14
14
  include EncryptedDataBag
15
+ include CachePathUsage
15
16
  end
@@ -0,0 +1,38 @@
1
+ require 'test_helper'
2
+ require 'knife-solo/config'
3
+
4
+ class KnifeSoloConfigTest < TestCase
5
+ def setup
6
+ super
7
+ @config = KnifeSolo::Config.new
8
+ end
9
+
10
+ def teardown
11
+ super
12
+ FileUtils.rm_f 'solo.rb'
13
+ end
14
+
15
+ def test_uses_cookbook_path_from_solo_rb_if_available
16
+ write_file('solo.rb', <<-RUBY)
17
+ knife[:solo_path] = "./custom"
18
+ cookbook_path ["./custom/path"]
19
+ RUBY
20
+ assert_equal "./custom/path", @config.cookbook_path
21
+ end
22
+
23
+ def test_reads_chef_root_path_from_knife_config_or_defaults_to_home
24
+ assert_equal './chef-solo', @config.chef_path
25
+ Chef::Config.knife[:solo_path] = "/tmp/custom-chef-solo"
26
+ assert_equal "/tmp/custom-chef-solo", @config.chef_path
27
+ end
28
+
29
+ def test_fails_validation_if_user_has_solo_rb_and_no_solo_path
30
+ Chef::Config.knife[:solo_path] = nil
31
+ write_file('solo.rb', <<-RUBY)
32
+ cookbook_path ["custom/path"]
33
+ RUBY
34
+ assert_raises KnifeSolo::Config::Error do
35
+ @config.validate!
36
+ end
37
+ end
38
+ end
@@ -16,18 +16,6 @@ class SoloCookTest < TestCase
16
16
  include KitchenHelper
17
17
  include ValidationHelper::ValidationTests
18
18
 
19
- def test_gets_destination_path_from_chef_config
20
- cmd = command
21
- Chef::Config.file_cache_path "/foo/chef-solo"
22
- assert_equal "/foo/chef-solo", cmd.chef_path
23
- end
24
-
25
- def test_gets_patch_path_from_chef_config
26
- cmd = command
27
- Chef::Config.cookbook_path ["/bar/chef-solo/cookbooks"]
28
- assert_equal "/bar/chef-solo/cookbooks/chef_solo_patches/libraries", cmd.patch_path
29
- end
30
-
31
19
  def test_chefignore_is_valid_object
32
20
  assert_instance_of Chef::Cookbook::Chefignore, command.chefignore
33
21
  end
@@ -152,8 +140,8 @@ class SoloCookTest < TestCase
152
140
  def command(*args)
153
141
  cmd = knife_command(Chef::Knife::SoloCook, *args)
154
142
  cmd.stubs(:check_chef_version)
155
- cmd.stubs(:rsync_kitchen)
156
143
  cmd.stubs(:add_patches)
144
+ cmd.stubs(:rsync)
157
145
  cmd.stubs(:stream_command).returns(SuccessfulResult.new)
158
146
  cmd
159
147
  end
@@ -0,0 +1,7 @@
1
+ name 'cache_using_cookbook'
2
+ maintainer 'Mat Schaffer'
3
+ maintainer_email 'mat@schaffer.me'
4
+ license 'MIT'
5
+ description 'Writes some data to the cache path.'
6
+ long_description 'This helps ensure that we can do this multiple times regardless of what user initiates the run.'
7
+ version '0.1.0'
@@ -0,0 +1,33 @@
1
+ #
2
+ # Cookbook Name:: cache_using_cookbook
3
+ # Recipe:: default
4
+ #
5
+ # Copyright 2013, Mat Schaffer
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining
8
+ # a copy of this software and associated documentation files (the
9
+ # "Software"), to deal in the Software without restriction, including
10
+ # without limitation the rights to use, copy, modify, merge, publish,
11
+ # distribute, sublicense, and/or sell copies of the Software, and to
12
+ # permit persons to whom the Software is furnished to do so, subject to
13
+ # the following conditions:
14
+ #
15
+ # The above copyright notice and this permission notice shall be
16
+ # included in all copies or substantial portions of the Software.
17
+ #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
+ #
26
+
27
+ container = Chef::Config[:file_cache_path] + "/test_dir"
28
+
29
+ directory container
30
+
31
+ file container + "/test_file" do
32
+ content "This was generated from run #{node['run_count']}"
33
+ end
@@ -3,6 +3,11 @@ class TestCase < MiniTest::Unit::TestCase
3
3
  super unless self.class == TestCase
4
4
  end
5
5
 
6
+ def write_file(file, contents)
7
+ FileUtils.mkpath(File.dirname(file))
8
+ File.open(file, 'w') { |f| f.print contents }
9
+ end
10
+
6
11
  def knife_command(cmd_class, *args)
7
12
  cmd_class.load_deps
8
13
  command = cmd_class.new(args)
@@ -15,25 +15,7 @@ module ValidationHelper
15
15
  end
16
16
  end
17
17
 
18
- module KitchenCommandTests
19
- include KitchenHelper
20
-
21
- def test_barks_outside_of_the_kitchen
22
- cmd = default_command
23
- cmd.ui.expects(:err).with(regexp_matches(/must be run inside .* kitchen/))
24
- outside_kitchen do
25
- assert_exits cmd
26
- end
27
- end
28
-
29
- # Returns a Knife instance that shoud run without other validation errors.
30
- def default_command
31
- command("somehost")
32
- end
33
- end
34
-
35
18
  module ValidationTests
36
19
  include SshCommandTests
37
- include KitchenCommandTests
38
20
  end
39
21
  end
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knife-solo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
5
- prerelease:
4
+ version: 0.3.0.pre1
5
+ prerelease: 6
6
6
  platform: ruby
7
7
  authors:
8
8
  - Mat Schaffer
@@ -204,11 +204,12 @@ files:
204
204
  - lib/knife-solo/bootstraps/freebsd.rb
205
205
  - lib/knife-solo/bootstraps/linux.rb
206
206
  - lib/knife-solo/bootstraps/sun_os.rb
207
+ - lib/knife-solo/config.rb
207
208
  - lib/knife-solo/deprecated_command.rb
208
209
  - lib/knife-solo/gitignore.rb
209
210
  - lib/knife-solo/info.rb
210
- - lib/knife-solo/kitchen_command.rb
211
211
  - lib/knife-solo/node_config_command.rb
212
+ - lib/knife-solo/resources/solo.rb
212
213
  - lib/knife-solo/ssh_command.rb
213
214
  - lib/knife-solo/tools.rb
214
215
  - test/bootstraps_test.rb
@@ -217,6 +218,7 @@ files:
217
218
  - test/integration/amazon_linux_2012_09_bootstrap_test.rb
218
219
  - test/integration/cases/apache2_bootstrap.rb
219
220
  - test/integration/cases/apache2_cook.rb
221
+ - test/integration/cases/cache_path_usage.rb
220
222
  - test/integration/cases/empty_cook.rb
221
223
  - test/integration/cases/encrypted_data_bag.rb
222
224
  - test/integration/centos5_6_test.rb
@@ -230,7 +232,7 @@ files:
230
232
  - test/integration/ubuntu12_04_bootstrap_test.rb
231
233
  - test/integration/ubuntu12_04_test.rb
232
234
  - test/integration_helper.rb
233
- - test/kitchen_command_test.rb
235
+ - test/knife-solo/config_test.rb
234
236
  - test/minitest/parallel.rb
235
237
  - test/node_config_command_test.rb
236
238
  - test/solo_bootstrap_test.rb
@@ -239,6 +241,8 @@ files:
239
241
  - test/solo_init_test.rb
240
242
  - test/solo_prepare_test.rb
241
243
  - test/ssh_command_test.rb
244
+ - test/support/cache_using_cookbook/metadata.rb
245
+ - test/support/cache_using_cookbook/recipes/default.rb
242
246
  - test/support/config.yml.example
243
247
  - test/support/data_bag_key
244
248
  - test/support/ec2_runner.rb
@@ -273,9 +277,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
273
277
  required_rubygems_version: !ruby/object:Gem::Requirement
274
278
  none: false
275
279
  requirements:
276
- - - ! '>='
280
+ - - ! '>'
277
281
  - !ruby/object:Gem::Version
278
- version: '0'
282
+ version: 1.3.1
279
283
  requirements: []
280
284
  rubyforge_project:
281
285
  rubygems_version: 1.8.24
@@ -289,6 +293,7 @@ test_files:
289
293
  - test/integration/amazon_linux_2012_09_bootstrap_test.rb
290
294
  - test/integration/cases/apache2_bootstrap.rb
291
295
  - test/integration/cases/apache2_cook.rb
296
+ - test/integration/cases/cache_path_usage.rb
292
297
  - test/integration/cases/empty_cook.rb
293
298
  - test/integration/cases/encrypted_data_bag.rb
294
299
  - test/integration/centos5_6_test.rb
@@ -302,7 +307,7 @@ test_files:
302
307
  - test/integration/ubuntu12_04_bootstrap_test.rb
303
308
  - test/integration/ubuntu12_04_test.rb
304
309
  - test/integration_helper.rb
305
- - test/kitchen_command_test.rb
310
+ - test/knife-solo/config_test.rb
306
311
  - test/minitest/parallel.rb
307
312
  - test/node_config_command_test.rb
308
313
  - test/solo_bootstrap_test.rb
@@ -311,6 +316,8 @@ test_files:
311
316
  - test/solo_init_test.rb
312
317
  - test/solo_prepare_test.rb
313
318
  - test/ssh_command_test.rb
319
+ - test/support/cache_using_cookbook/metadata.rb
320
+ - test/support/cache_using_cookbook/recipes/default.rb
314
321
  - test/support/config.yml.example
315
322
  - test/support/data_bag_key
316
323
  - test/support/ec2_runner.rb
@@ -1,26 +0,0 @@
1
- module KnifeSolo
2
- module KitchenCommand
3
- def self.required_files
4
- %w(solo.rb)
5
- end
6
-
7
- def validate_kitchen!
8
- unless required_files_present?
9
- ui.fatal "This command must be run inside a Chef solo kitchen."
10
- exit 1
11
- end
12
- end
13
-
14
- def required_files_present?
15
- KitchenCommand.required_files.inject(true) do |m, f|
16
- check = File.exists?(f)
17
- warn_for_required_file(f) unless check
18
- m && check
19
- end
20
- end
21
-
22
- def warn_for_required_file(file)
23
- ui.error "#{file} is a required file/directory"
24
- end
25
- end
26
- end
@@ -1,31 +0,0 @@
1
- require 'test_helper'
2
- require 'support/kitchen_helper'
3
-
4
- require 'chef/knife'
5
- require 'knife-solo/kitchen_command'
6
-
7
- class DummyKitchenCommand < Chef::Knife
8
- include KnifeSolo::KitchenCommand
9
- end
10
-
11
- class KitchenCommandTest < TestCase
12
- include KitchenHelper
13
-
14
- def test_barks_outside_of_the_kitchen
15
- cmd = command
16
- cmd.ui.expects(:err).with(regexp_matches(/must be run inside .* kitchen/))
17
- outside_kitchen do
18
- assert_exits { cmd.validate_kitchen! }
19
- end
20
- end
21
-
22
- def test_runs_when_in_a_kitchen
23
- in_kitchen do
24
- command.validate_kitchen!
25
- end
26
- end
27
-
28
- def command(*args)
29
- knife_command(DummyKitchenCommand, *args)
30
- end
31
- end