berkshelf 1.4.5 → 1.4.6

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.
@@ -17,6 +17,8 @@ module Berkshelf
17
17
  Archive::Tar::Minitar.unpack(Zlib::GzipReader.new(File.open(target, 'rb')), destination)
18
18
  elsif is_tar_file(target)
19
19
  Archive::Tar::Minitar.unpack(target, destination)
20
+ else
21
+ raise Berkshelf::UnknownCompressionType.new(target)
20
22
  end
21
23
  destination
22
24
  end
@@ -43,7 +45,7 @@ module Berkshelf
43
45
  end
44
46
 
45
47
  def is_tar_file(path)
46
- IO.binread(path, 8, 257) == "ustar \0"
48
+ IO.binread(path, 8, 257).to_s == "ustar\x0000"
47
49
  end
48
50
  end
49
51
 
@@ -163,4 +163,92 @@ module Berkshelf
163
163
  "Unknown site shortname: #{@shortname.inspect}. Supported shortnames are: #{SiteLocation::SHORTNAMES.keys.map(&:inspect).join(',')}"
164
164
  end
165
165
  end
166
+
167
+ class OutdatedCookbookSource < BerkshelfError
168
+ status_code(128)
169
+
170
+ # @return [Berkshelf::CookbookSource]
171
+ attr_reader :locked_source, :source
172
+
173
+ # @param [Berkshelf::CookbookSource] source
174
+ # the cookbook source that is outdated
175
+ def initialize(locked_source, source)
176
+ @locked_source = locked_source
177
+ @source = source
178
+ end
179
+
180
+ def to_s
181
+ [
182
+ "Berkshelf could not find compatible versions for cookbook '#{source.name}':",
183
+ " In Berksfile:",
184
+ " #{locked_source.name} (#{locked_source.locked_version})",
185
+ "",
186
+ " In Berksfile.lock:",
187
+ " #{source.name} (#{source.version_constraint})",
188
+ "",
189
+ "Try running `berks update #{source.name}, which will try to find '#{source.name}' matching '#{source.version_constraint}'."
190
+ ].join("\n")
191
+ end
192
+ end
193
+
194
+ class EnvironmentNotFound < BerkshelfError
195
+ status_code(129)
196
+
197
+ def initialize(environment_name)
198
+ @environment_name = environment_name
199
+ end
200
+
201
+ def to_s
202
+ %Q[The environment "#{@environment_name}" does not exist.]
203
+ end
204
+ end
205
+
206
+ class ChefConnectionError < BerkshelfError
207
+ status_code(130)
208
+
209
+ def to_s
210
+ "There was an error connecting to the chef server."
211
+ end
212
+ end
213
+
214
+ # @author Seth Vargo <sethvargo@gmail.com>
215
+ class UnknownCompressionType < BerkshelfError
216
+ status_code(131)
217
+
218
+ def initialize(destination)
219
+ @destination = destination
220
+ end
221
+
222
+ def to_s
223
+ "The file at '#{@destination}' is not a known compression type!"
224
+ end
225
+ end
226
+
227
+ # @author Seth Vargo <sethvargo@gmail.com>
228
+ #
229
+ # Raised when a cookbook or its recipes contain a space or invalid
230
+ # character in the path.
231
+ #
232
+ # @param [Berkshelf::CachedCookbook] cookbook
233
+ # the cookbook that failed validation
234
+ # @param [Array<#to_s>] files
235
+ # the list of files that were not valid
236
+ class InvalidCookbookFiles < BerkshelfError
237
+ status_code(132)
238
+
239
+ def initialize(cookbook, files)
240
+ @cookbook = cookbook
241
+ @files = files
242
+ end
243
+
244
+ def to_s
245
+ [
246
+ "The cookbook '#{@cookbook.cookbook_name}' has invalid filenames:",
247
+ "",
248
+ " " + @files.map(&:to_s).join("\n "),
249
+ "",
250
+ "Please note, spaces are not a valid character in filenames."
251
+ ].join("\n")
252
+ end
253
+ end
166
254
  end
@@ -174,7 +174,8 @@ module Berkshelf
174
174
  else
175
175
  conn.cookbook.latest_version(name)
176
176
  end
177
- rescue Ridley::Errors::HTTPNotFound
177
+ rescue Ridley::Errors::HTTPNotFound,
178
+ Ridley::Errors::ResourceNotFound
178
179
  @target_cookbook = nil
179
180
  end
180
181
 
@@ -63,23 +63,21 @@ module Berkshelf
63
63
  end
64
64
 
65
65
  tmp_path = rel ? File.join(clone, rel) : clone
66
- puts "File.chef_cookbook?(tmp_path): #{File.chef_cookbook?(tmp_path)}"
67
66
  unless File.chef_cookbook?(tmp_path)
68
67
  msg = "Cookbook '#{name}' not found at git: #{uri}"
69
68
  msg << " with branch '#{branch}'" if branch
70
69
  msg << " at path '#{rel}'" if rel
71
70
  raise CookbookNotFound, msg
72
71
  end
73
-
72
+
74
73
  cb_path = File.join(destination, "#{name}-#{branch_name}")
75
74
  FileUtils.rm_rf(cb_path)
76
75
  FileUtils.mv(tmp_path, cb_path)
77
-
76
+
78
77
  cached = CachedCookbook.from_store_path(cb_path)
79
78
  validate_cached(cached)
80
79
 
81
80
  set_downloaded_status(true)
82
- puts "cached.class: #{cached.class}"
83
81
  cached
84
82
  end
85
83
 
@@ -22,7 +22,9 @@ module Berkshelf
22
22
  @name = name
23
23
  @version_constraint = version_constraint
24
24
 
25
- api_uri = if options[:site].nil? || SHORTNAMES.has_key?(options[:site])
25
+ api_uri = if options[:site].nil?
26
+ SHORTNAMES[:opscode]
27
+ elsif SHORTNAMES.has_key?(options[:site])
26
28
  SHORTNAMES[options[:site]]
27
29
  elsif options[:site].kind_of?(Symbol)
28
30
  raise InvalidSiteShortnameError.new(options[:site])
data/lib/berkshelf/ui.rb CHANGED
@@ -10,12 +10,16 @@ module Berkshelf
10
10
  @mute = false
11
11
  end
12
12
 
13
- def say(message = "", color = nil, force_new_line = nil)
13
+ def say(message = '', color = nil, force_new_line = (message.to_s !~ /( |\t)\Z/))
14
14
  return if quiet?
15
15
 
16
- super(message, color)
16
+ super(message, color, force_new_line)
17
+ end
18
+
19
+ # @see {say}
20
+ def info(message = '', color = nil, force_new_line = (message.to_s !~ /( |\t)\Z/))
21
+ say(message, color, force_new_line)
17
22
  end
18
- alias_method :info, :say
19
23
 
20
24
  def say_status(status, message, log_status = true)
21
25
  return if quiet?
@@ -25,7 +29,7 @@ module Berkshelf
25
29
 
26
30
  def warn(message, color = :yellow)
27
31
  return if quiet?
28
-
32
+
29
33
  say(message, color)
30
34
  end
31
35
 
@@ -1,3 +1,3 @@
1
1
  module Berkshelf
2
- VERSION = "1.4.5"
2
+ VERSION = "1.4.6"
3
3
  end
@@ -0,0 +1,27 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIEpQIBAAKCAQEAs3u5qfmdEWtzYHvXpbQRyefhUjeTG7nwhn/LaYY6ou19xxW0
3
+ I5MKSBqCxUCHqODRc7ox8zSF37x3jMBHbSczOcfbWsSe/qGnmvZZQhHmXCje2zkW
4
+ ByaRHmmatzkz1aAqAmZm/wdSuVLXytsbrPXuaj/MiHa6QH3e/ZFaYME7rMkouqfC
5
+ pUlSa2tZ9Ko1ZCCwjkiifuP4yQFsS6/G6b8c7F8wdq4byfJ9o6FN34lJHrzfG0ZV
6
+ hwS47Bdn6FDBQ6PVxrBsvQNE2n7QlNLfXWi4Tb8OpmQif01FjxleAr5kamx3GD+s
7
+ jC7fKHE9bZ0apZ1MVmkz9PhFmOigV5jl9Att+QIDAQABAoIBAQCCG6qXgQ9PVWkq
8
+ BBxrToGmr6UzCH5nlv65QWKfeGKBQU/wRdd0Al9trWomu4Sb831iOxOCjgyOB/1R
9
+ 1wDwK36C4FIvFmF7jIwHVZWWw4sOO8JxgIxrWpXQShWRxLHCpnxNiRYYwaJCHb+4
10
+ meUSGKVf+Ce4tPiHT7eacQfnI6yyr1hWusKu0I8w7NsfeNc+/Rpne6mifLfaB/9u
11
+ b9kgfD15HGEsuUaMLZ/y1HFWvw2G2Og1cDrIpBIVtUAhA+DnjjLe/YoETeSmQAxH
12
+ ioQpJJ/gSqtTczIoyPXXiwaF5wUTQrsn5zZhTs9mAQy7hcSR92IH2xBSmK3+wlz0
13
+ vHZIq9rRAoGBAOeRUTRDgj+f+BlH1qFqf4EfkBN5quVM2808LYBGZWfA5/6o9jSN
14
+ AM84VXq3S8Wy5V6UMcSv4mOqEr3tEUYE8or9r/RxzpGahSdi8Ttju9vvpJH5I3xr
15
+ xx2ZK/vlrAfr6JHlE4bqqc5unCslUt2/liCWpERQ3cFcPydQb7Imrm+DAoGBAMZr
16
+ mcxBeMyQHG6Kcpc7EQXZ5i7a8T6ksPu7FbAZ70Meb9UMtVIYpVBalutCXKhl7D4K
17
+ qrCmV2gQryBz+S7AecFZSKvXdb7ueYzf8EcI/v+loNu9v9/4m4YV3bPBkMhW5kcK
18
+ xFnVIsYqUlR+dsS8JfjSCpk4lePVSSt7B26eIFfTAoGBAJHPDKSuBWtunNe+RkUp
19
+ O9PgPeYlbBgqBxT52WS17tAfxXSyiySXzHSuchRtKgb4GDkvcw73+MLsqhRxG7lN
20
+ EDO4fXyb1IgWFdWxFVhh+j4IbUWE7HVBoAThF7Lq8SGjx7Nl3J/NTtKvDyKTw9Pg
21
+ +PTYJeLmUFuabCGjIlG4zYllAoGBAIwe5oB4597GEl35xUyI+M+B/myuTtknIpjS
22
+ mFFBL1bdwqnYjJ+KKgwhvRwsRBTjzT5O+BVBks45ogKwA5OBdzoUXB6GTG9mJ05V
23
+ wm/XqYRNqdgkGsEG5oV9IZBUrHLd80bOErVBr4nzzyo+GI98MvCRG8zySd+X+lEL
24
+ U8dJQZvjAoGAWorll+fomfie6t5XbkpwMo8rn60yFUiRE7HWxA2qDj3IpoE6SfNE
25
+ eOpsf1Zzx30r8answ9lPnd753ACdgNzE66ScWD+cQeB6OlMZMaW5tVSjddZ7854L
26
+ 00znt8b1OLkVY33xfsa89wKH343304BhVHABPMxm5Leua/H21/BqSK0=
27
+ -----END RSA PRIVATE KEY-----
@@ -4,8 +4,8 @@ log_level :info
4
4
  log_location STDOUT
5
5
  node_name "berkshelf"
6
6
  client_key "#{current_dir}/berkshelf.pem"
7
- validation_client_name "chef-validator"
8
- validation_key "#{current_dir}/chef-validator.pem"
7
+ validation_client_name "validator"
8
+ validation_key "#{current_dir}/validator.pem"
9
9
  chef_server_url "http://localhost:4000"
10
10
  cache_type 'BasicFile'
11
11
  cache_options( :path => "#{ENV['HOME']}/.chef/checksums" )
@@ -0,0 +1,27 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIEowIBAAKCAQEAxvMbzsVt0PJ0ozcpQZC+zpaWYAZe/nHnSFeTkm9BAtQUA8vp
3
+ cKMJTXNw4Lm3jcotrPATMgGgwVG7ram689JcQSnwSgIFinr5ZLRB22qyGdqHHmAf
4
+ w4RVde6dJON2IqI51JzQ5Pfs+M1SYcKiCzcBHvFddug5VcMjipFLv7QPKDmal8Ep
5
+ tOtRhb8Ad2DBXV7gX3e8ZaKfQgA0uc07g1KmcjR7vOG25nxY6NRxTwWn5+uMVgCp
6
+ 1xjbBeq7XF2gJPYVNsNRu8C3/rMX7D3NuKpJGj3CsKOtECREsq+7lk7A7OPzrP0g
7
+ Um/dUSeV99FLavrJNZ8TRc+BLZD/RiE1x0wG9wIDAQABAoIBAAbRchSGA5tzk7e8
8
+ Pje3BDMESicEUOEbejeqeK4+DdZQ+lae+GMZ00nKOQYal0XOtf4FREMkdyPo7yum
9
+ c3fDr9Gz5D5FD3eNe1qOKuugHnZwXM0Xsj77HAqsoMoQ2Y2aTa0Rqr8OGBr2vmoH
10
+ R5Jm0i0DTJa0orJju6YWEKiDPTm9oCT025M3G4kswM4jnzQiTciksfEYJGIK1Alk
11
+ Lcct/8TtyoYNhzYfzFi2wIQx4Iy6o/2AqWjvcJT2RI3cge5CBOXR7Y1Zqt5/vWm+
12
+ MvSy+krujFTTKpJKbatOsRGoCX6e8IcIQ4MtOj9jSPQPvGcQrjEdks6+zKID6INW
13
+ ZZYrvqECgYEA8EKB/oYzNueoBvaFcw1ONUNScYnr9IS/7oZnciw53cMwDumsH9qB
14
+ NbEH6m1/2EQhOU5KoAQX2qd8KNQ6oIL1ae51ACtdEBP9Sb9j2q+IlEOf3bLga+w1
15
+ DXeQ0wx4ZHyF6a2AJK4qVO+nDnYw074VxaApLXDyfXpIS7N9lOJxeb8CgYEA0/vF
16
+ mt/+r6v2YOVWtSah44lIyaDj3N6fjYcI34aJvowwe+Njfnd2o4BkqhthQKOnl6FI
17
+ SQPrLBdwc4OvN9oWMZHX2b0ols0Bf5ZxAfqMvCS2JG+SiiZT+p+cPnCitfPZ6zn7
18
+ 5SMpVMqlMS8GxNze8ZkieQ7PaF28rF0xUJZIkMkCgYEAwspJNqB7OVKMCkkoXOU2
19
+ uTxBxUe7A9309mAF0q1EpSUw+4Y8RP8UrwE+l7P7aM2j2iA9pIptBJuxsDCQ7739
20
+ Vss8FM0TgIuUWYxQWubh5sMFA+uYxCcXxDliM5nyqhXDRHekYxjJvV8npDPy1llQ
21
+ sY9ukyb1kwHnR2jYsjL9KWUCgYAmB1vKzfZVs4bOmTX154lRVXaOXWOjYvjCnf/0
22
+ gaFCYsnr374gmPPanxTwA1tuCi3toMxj9OUCku3kezI61c/3co+Di1C1xO9I4UdC
23
+ sJ0Av6FBZham2/ti0bFo7jHybF2iulM7JxSqFnSOHz6aoHkKZItvpj2FHpPTZCCN
24
+ sXgxKQKBgDyBsl4/LCG+eQrxaL6Y7DHP9oNTw5hRbQWlZlXfygyUbKCqj1OfOrVu
25
+ hDAn/ElMLgSgRbI8nXq68cu6UE4wO4Di6fQyCb2pP7tgS+0swbq85YoMbHh/z+yN
26
+ WUvLQHfN4RHJStY3JX/cBcSoIiArNbuFcPThM02YBDhbiW+NQhZV
27
+ -----END RSA PRIVATE KEY-----
data/spec/spec_helper.rb CHANGED
@@ -15,7 +15,7 @@ Spork.prefork do
15
15
 
16
16
  APP_ROOT = File.expand_path('../../', __FILE__)
17
17
  ENV["BERKSHELF_PATH"] = File.join(APP_ROOT, "spec", "tmp", "berkshelf")
18
- ENV["BERKSHELF_CHEF_CONFIG"] = File.join(APP_ROOT, "spec", "knife.rb")
18
+ ENV["BERKSHELF_CHEF_CONFIG"] = File.join(APP_ROOT, "spec", "config", "knife.rb")
19
19
 
20
20
  Dir[File.join(APP_ROOT, "spec/support/**/*.rb")].each {|f| require f}
21
21
 
@@ -36,6 +36,15 @@ Spork.prefork do
36
36
  config.filter_run focus: true
37
37
  config.run_all_when_everything_filtered = true
38
38
 
39
+ config.before(:suite) do
40
+ Berkshelf::RSpec::ChefServer.start
41
+ WebMock.disable_net_connect!(allow_localhost: true, net_http_connect_on_start: true)
42
+ end
43
+
44
+ config.after(:suite) do
45
+ Berkshelf::RSpec::ChefServer.stop
46
+ end
47
+
39
48
  config.before(:each) do
40
49
  clean_tmp_path
41
50
  Berkshelf.cookbook_store = Berkshelf::CookbookStore.new(tmp_path.join("downloader_tmp"))
@@ -155,8 +164,6 @@ Spork.prefork do
155
164
  def run(cmd)
156
165
  `#{cmd}`
157
166
  end
158
-
159
- Berkshelf::RSpec::Knife.load_knife_config(File.join(APP_ROOT, 'spec/knife.rb'))
160
167
  end
161
168
 
162
169
  Spork.each_run do
@@ -24,7 +24,8 @@ module Berkshelf
24
24
  else
25
25
  ridley.cookbook.delete(name, version)
26
26
  end
27
- rescue Ridley::Errors::HTTPNotFound
27
+ rescue Ridley::Errors::HTTPNotFound,
28
+ Ridley::Errors::ResourceNotFound
28
29
  true
29
30
  end
30
31
 
@@ -36,7 +37,8 @@ module Berkshelf
36
37
  else
37
38
  !versions.find { |ver| ver == version }.nil?
38
39
  end
39
- rescue Ridley::Errors::HTTPNotFound
40
+ rescue Ridley::Errors::HTTPNotFound,
41
+ Ridley::Errors::ResourceNotFound
40
42
  false
41
43
  end
42
44
 
@@ -0,0 +1,73 @@
1
+ require 'chef_zero/server'
2
+
3
+ module Berkshelf::RSpec
4
+ module ChefServer
5
+ PORT = 8889
6
+
7
+ class << self
8
+ def clear_request_log
9
+ @request_log = Array.new
10
+ end
11
+
12
+ def request_log
13
+ @request_log ||= Array.new
14
+ end
15
+
16
+ def server
17
+ @server ||= ChefZero::Server.new(port: PORT, generate_real_keys: false)
18
+ end
19
+
20
+ def server_url
21
+ (@server && @server.url) || "http://localhost:#{PORT}"
22
+ end
23
+
24
+ def start
25
+ server.start_background
26
+ server.on_response do |request, response|
27
+ request_log << [ request, response ]
28
+ end
29
+ clear_request_log
30
+
31
+ server
32
+ end
33
+
34
+ def stop
35
+ @server.stop if running?
36
+ end
37
+
38
+ def running?
39
+ @server && @server.running?
40
+ end
41
+ end
42
+
43
+ def chef_server
44
+ ChefServer.server
45
+ end
46
+
47
+ def chef_client(name, hash = Hash.new)
48
+ load_data(:clients, name, hash)
49
+ end
50
+
51
+ def chef_data_bag(name, hash = Hash.new)
52
+ ChefServer.server.load_data({ 'data' => { name => hash }})
53
+ end
54
+
55
+ def chef_environment(name, hash = Hash.new)
56
+ load_data(:environments, name, hash)
57
+ end
58
+
59
+ def chef_node(name, hash = Hash.new)
60
+ load_data(:nodes, name, hash)
61
+ end
62
+
63
+ def chef_role(name, hash = Hash.new)
64
+ load_data(:roles, name, hash)
65
+ end
66
+
67
+ private
68
+
69
+ def load_data(key, name, hash)
70
+ ChefServer.server.load_data({ key.to_s => { name => MultiJson.encode(hash) }})
71
+ end
72
+ end
73
+ end
@@ -3,7 +3,7 @@
3
3
  module Berkshelf
4
4
  module RSpec
5
5
  module FileSystemMatchers
6
- class File < ::File
6
+ class FileMatcher
7
7
  def initialize(name, &block)
8
8
  @contents = []
9
9
  @negative_contents = []
@@ -27,7 +27,7 @@ module Berkshelf
27
27
  throw :failure, root.join(@name)
28
28
  end
29
29
 
30
- contents = ::File.read(root.join(@name))
30
+ contents = File.read(root.join(@name))
31
31
 
32
32
  @contents.each do |string|
33
33
  unless contents.include?(string)
@@ -43,7 +43,7 @@ module Berkshelf
43
43
  end
44
44
  end
45
45
 
46
- class Directory
46
+ class DirectoryMatcher
47
47
  attr_reader :tree
48
48
 
49
49
  def initialize(root = nil, &block)
@@ -54,12 +54,12 @@ module Berkshelf
54
54
  end
55
55
 
56
56
  def directory(name, &block)
57
- @tree[name] = block_given? && Directory.new(location(name), &block)
57
+ @tree[name] = block_given? && DirectoryMatcher.new(location(name), &block)
58
58
  end
59
59
 
60
60
  def file(name, &block)
61
61
  silence_warnings do
62
- @tree[name] = Berkshelf::RSpec::FileSystemMatchers::File.new(location(name), &block)
62
+ @tree[name] = FileMatcher.new(location(name), &block)
63
63
  end
64
64
  end
65
65
 
@@ -92,7 +92,7 @@ module Berkshelf
92
92
  end
93
93
  end
94
94
 
95
- class Root < Directory
95
+ class RootMatcher < DirectoryMatcher
96
96
  def failure_message
97
97
  if @failure.is_a?(Array) && @failure[0] == :not
98
98
  if @failure[2]
@@ -125,7 +125,7 @@ module Berkshelf
125
125
  end
126
126
 
127
127
  def have_structure(&block)
128
- Root.new(&block)
128
+ RootMatcher.new(&block)
129
129
  end
130
130
  end
131
131
  end