berkshelf 1.4.5 → 1.4.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -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