berkshelf 7.0.9 → 7.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +3 -12
- data/Rakefile +2 -2
- data/berkshelf.gemspec +3 -4
- data/bin/berks +1 -1
- data/lib/berkshelf.rb +7 -8
- data/lib/berkshelf/api_client.rb +2 -2
- data/lib/berkshelf/api_client/chef_server_connection.rb +4 -6
- data/lib/berkshelf/api_client/remote_cookbook.rb +1 -1
- data/lib/berkshelf/berksfile.rb +32 -32
- data/lib/berkshelf/chef_config_compat.rb +1 -1
- data/lib/berkshelf/cli.rb +5 -5
- data/lib/berkshelf/community_rest.rb +3 -3
- data/lib/berkshelf/config.rb +2 -2
- data/lib/berkshelf/cookbook_store.rb +2 -4
- data/lib/berkshelf/core_ext/file_utils.rb +3 -3
- data/lib/berkshelf/downloader.rb +5 -5
- data/lib/berkshelf/errors.rb +3 -0
- data/lib/berkshelf/file_syncer.rb +10 -12
- data/lib/berkshelf/installer.rb +7 -7
- data/lib/berkshelf/location.rb +3 -3
- data/lib/berkshelf/locations/git.rb +6 -12
- data/lib/berkshelf/lockfile.rb +9 -9
- data/lib/berkshelf/mixin/git.rb +2 -2
- data/lib/berkshelf/packager.rb +5 -7
- data/lib/berkshelf/shell.rb +1 -1
- data/lib/berkshelf/shell_out.rb +4 -3
- data/lib/berkshelf/source.rb +2 -2
- data/lib/berkshelf/source_uri.rb +1 -1
- data/lib/berkshelf/ssl_policies.rb +5 -7
- data/lib/berkshelf/uploader.rb +36 -36
- data/lib/berkshelf/validator.rb +2 -8
- data/lib/berkshelf/version.rb +1 -1
- data/lib/berkshelf/visualizer.rb +2 -2
- data/spec/spec_helper.rb +1 -1
- data/spec/support/git.rb +18 -18
- data/spec/support/path_helpers.rb +4 -4
- data/spec/unit/berkshelf/berkshelf/api_client/chef_server_connection_spec.rb +65 -0
- data/spec/unit/berkshelf/core_ext/file_utils_spec.rb +2 -2
- data/spec/unit/berkshelf/locations/git_spec.rb +2 -5
- data/spec/unit/berkshelf/ridley_compat_spec.rb +1 -1
- data/spec/unit/berkshelf/source_spec.rb +22 -12
- data/spec/unit/berkshelf/ssl_policies_spec.rb +0 -1
- data/spec/unit/berkshelf/validator_spec.rb +0 -13
- metadata +11 -10
data/lib/berkshelf/installer.rb
CHANGED
@@ -19,13 +19,13 @@ module Berkshelf
|
|
19
19
|
def build_universe
|
20
20
|
berksfile.sources.collect do |source|
|
21
21
|
Thread.new do
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
22
|
+
|
23
|
+
Berkshelf.formatter.msg("Fetching cookbook index from #{source}...")
|
24
|
+
source.build_universe
|
25
|
+
rescue Berkshelf::APIClientError => ex
|
26
|
+
Berkshelf.formatter.warn "Error retrieving universe from source: #{source}"
|
27
|
+
Berkshelf.formatter.warn " * [#{ex.class}] #{ex}"
|
28
|
+
|
29
29
|
end
|
30
30
|
end.map(&:join)
|
31
31
|
end
|
data/lib/berkshelf/location.rb
CHANGED
@@ -28,9 +28,9 @@ module Berkshelf
|
|
28
28
|
|
29
29
|
private
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
# Load the correct location from the given options.
|
32
|
+
#
|
33
|
+
# @return [Class, nil]
|
34
34
|
def klass_from_options(options)
|
35
35
|
options.each do |key, _|
|
36
36
|
id = key.to_s.capitalize
|
@@ -37,28 +37,22 @@ module Berkshelf
|
|
37
37
|
scratch_path = Pathname.new(Dir.mktmpdir)
|
38
38
|
|
39
39
|
if cached?
|
40
|
-
|
41
|
-
git %{fetch --force --tags #{uri} "refs/heads/*:refs/heads/*"}
|
42
|
-
end
|
40
|
+
git(%{fetch --force --tags #{uri} "refs/heads/*:refs/heads/*"}, cwd: cache_path.to_s)
|
43
41
|
else
|
44
42
|
git %{clone #{uri} "#{cache_path}" --bare --no-hardlinks}
|
45
43
|
end
|
46
44
|
|
47
|
-
|
48
|
-
@revision ||= git %{rev-parse #{@rev_parse}}
|
49
|
-
end
|
45
|
+
@revision ||= git(%{rev-parse #{@rev_parse}}, cwd: cache_path.to_s)
|
50
46
|
|
51
47
|
# Clone into a scratch directory for validations
|
52
48
|
git %{clone --no-checkout "#{cache_path}" "#{scratch_path}"}
|
53
49
|
|
54
50
|
# Make sure the scratch directory is up-to-date and account for rel paths
|
55
|
-
|
56
|
-
|
57
|
-
git %{reset --hard #{@revision}}
|
51
|
+
git(%{fetch --force --tags "#{cache_path}"}, cwd: scratch_path.to_s)
|
52
|
+
git(%{reset --hard #{@revision}}, cwd: scratch_path.to_s)
|
58
53
|
|
59
|
-
|
60
|
-
|
61
|
-
end
|
54
|
+
if rel
|
55
|
+
git(%{filter-branch --subdirectory-filter "#{rel}" --force}, cwd: scratch_path.to_s)
|
62
56
|
end
|
63
57
|
|
64
58
|
# Validate the scratched path is a valid cookbook
|
data/lib/berkshelf/lockfile.rb
CHANGED
@@ -511,8 +511,8 @@ module Berkshelf
|
|
511
511
|
"#<Berkshelf::Lockfile #{Pathname.new(filepath).basename}, dependencies: #{dependencies.inspect}>"
|
512
512
|
end
|
513
513
|
|
514
|
-
|
515
|
-
|
514
|
+
# The class responsible for parsing the lockfile and turning it into a
|
515
|
+
# useful data structure.
|
516
516
|
class LockfileParser
|
517
517
|
NAME_VERSION = '(?! )(.*?)(?: \(([^-]*)(?:-(.*))?\))?'.freeze
|
518
518
|
DEPENDENCY_PATTERN = /^ {2}#{NAME_VERSION}$/.freeze
|
@@ -599,9 +599,9 @@ module Berkshelf
|
|
599
599
|
|
600
600
|
private
|
601
601
|
|
602
|
-
|
603
|
-
|
604
|
-
|
602
|
+
# Parse a dependency line.
|
603
|
+
#
|
604
|
+
# @param [String] line
|
605
605
|
def parse_dependency(line)
|
606
606
|
if line =~ DEPENDENCY_PATTERN
|
607
607
|
name, version = $1, $2
|
@@ -615,9 +615,9 @@ module Berkshelf
|
|
615
615
|
end
|
616
616
|
end
|
617
617
|
|
618
|
-
|
619
|
-
|
620
|
-
|
618
|
+
# Parse a graph line.
|
619
|
+
#
|
620
|
+
# @param [String] line
|
621
621
|
def parse_graph(line)
|
622
622
|
if line =~ DEPENDENCY_PATTERN
|
623
623
|
name, version = $1, $2
|
@@ -631,7 +631,7 @@ module Berkshelf
|
|
631
631
|
end
|
632
632
|
end
|
633
633
|
|
634
|
-
|
634
|
+
# The class representing an internal graph.
|
635
635
|
class Graph
|
636
636
|
include Enumerable
|
637
637
|
|
data/lib/berkshelf/mixin/git.rb
CHANGED
@@ -13,12 +13,12 @@ module Berkshelf
|
|
13
13
|
#
|
14
14
|
# @raise [String]
|
15
15
|
# the +$stdout+ from the command
|
16
|
-
def git(command, error = true)
|
16
|
+
def git(command, error = true, **kwargs)
|
17
17
|
unless Berkshelf.which("git") || Berkshelf.which("git.exe") || Berkshelf.which("git.bat")
|
18
18
|
raise GitNotInstalled.new
|
19
19
|
end
|
20
20
|
|
21
|
-
response = shell_out(%{git #{command}})
|
21
|
+
response = shell_out(%{git #{command}}, **kwargs)
|
22
22
|
|
23
23
|
if response.error?
|
24
24
|
raise GitCommandError.new(command, cache_path, response.stderr)
|
data/lib/berkshelf/packager.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require "archive/tar/minitar"
|
2
|
-
require "zlib"
|
2
|
+
require "zlib" unless defined?(Zlib)
|
3
3
|
|
4
4
|
module Berkshelf
|
5
5
|
# A class for archiving and compressing directory containing one or more cookbooks.
|
@@ -40,10 +40,8 @@ module Berkshelf
|
|
40
40
|
# @return [String]
|
41
41
|
# path to the generated archive
|
42
42
|
def run(source)
|
43
|
-
|
44
|
-
|
45
|
-
Archive::Tar::Minitar.pack(Dir.glob("*"), tgz)
|
46
|
-
end
|
43
|
+
tgz = Zlib::GzipWriter.new(File.open(out_file, "wb"))
|
44
|
+
Archive::Tar::Minitar.pack(Dir.glob("#{source}/*"), tgz)
|
47
45
|
|
48
46
|
out_file
|
49
47
|
rescue SystemCallError => ex
|
@@ -64,10 +62,10 @@ module Berkshelf
|
|
64
62
|
|
65
63
|
private
|
66
64
|
|
67
|
-
|
65
|
+
# @return [String]
|
68
66
|
attr_reader :out_dir
|
69
67
|
|
70
|
-
|
68
|
+
# @return [String]
|
71
69
|
attr_reader :filename
|
72
70
|
end
|
73
71
|
end
|
data/lib/berkshelf/shell.rb
CHANGED
data/lib/berkshelf/shell_out.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require "mixlib/shellout"
|
1
|
+
require "mixlib/shellout" unless defined?(Mixlib::ShellOut)
|
2
2
|
|
3
3
|
module Berkshelf
|
4
4
|
module ShellOut
|
@@ -8,8 +8,9 @@ module Berkshelf
|
|
8
8
|
cmd
|
9
9
|
end
|
10
10
|
|
11
|
-
def shell_out!(*args)
|
12
|
-
cmd =
|
11
|
+
def shell_out!(*args, **options)
|
12
|
+
cmd = Mixlib::ShellOut.new(*args, **options)
|
13
|
+
cmd.run_command
|
13
14
|
cmd.error!
|
14
15
|
cmd
|
15
16
|
end
|
data/lib/berkshelf/source.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require_relative "api-client"
|
2
2
|
require_relative "chef_repo_universe"
|
3
3
|
require_relative "ssl_policies"
|
4
|
-
require "openssl"
|
4
|
+
require "openssl" unless defined?(OpenSSL)
|
5
5
|
|
6
6
|
module Berkshelf
|
7
7
|
class Source
|
@@ -132,7 +132,7 @@ module Berkshelf
|
|
132
132
|
#
|
133
133
|
# @return [APIClient::RemoteCookbook]
|
134
134
|
def latest(name)
|
135
|
-
versions(name).
|
135
|
+
versions(name).max
|
136
136
|
end
|
137
137
|
|
138
138
|
# @param [String] name
|
data/lib/berkshelf/source_uri.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require "openssl"
|
1
|
+
require "openssl" unless defined?(OpenSSL)
|
2
2
|
|
3
3
|
module Berkshelf
|
4
4
|
class SSLPolicy
|
@@ -20,7 +20,7 @@ module Berkshelf
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def trusted_certs_dir
|
23
|
-
config_dir = Berkshelf.config.chef.trusted_certs_dir.to_s.tr(
|
23
|
+
config_dir = Berkshelf.config.chef.trusted_certs_dir.to_s.tr("\\", "/")
|
24
24
|
if config_dir.empty? || !::File.exist?(config_dir)
|
25
25
|
File.join(ENV["HOME"], ".chef", "trusted_certs")
|
26
26
|
else
|
@@ -29,11 +29,9 @@ module Berkshelf
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def set_custom_certs
|
32
|
-
Dir.
|
33
|
-
::
|
34
|
-
|
35
|
-
add_trusted_cert(cert)
|
36
|
-
end
|
32
|
+
::Dir.glob("#{trusted_certs_dir}/{*.crt,*.pem}").each do |cert|
|
33
|
+
cert = OpenSSL::X509::Certificate.new(IO.read(cert))
|
34
|
+
add_trusted_cert(cert)
|
37
35
|
end
|
38
36
|
end
|
39
37
|
end
|
data/lib/berkshelf/uploader.rb
CHANGED
@@ -45,10 +45,10 @@ module Berkshelf
|
|
45
45
|
|
46
46
|
private
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
48
|
+
# Upload the list of cookbooks to the Chef Server, with some exception
|
49
|
+
# wrapping.
|
50
|
+
#
|
51
|
+
# @param [Array<String>] cookbooks
|
52
52
|
def upload(cookbooks)
|
53
53
|
Berkshelf.log.info "Starting upload"
|
54
54
|
|
@@ -59,41 +59,41 @@ module Berkshelf
|
|
59
59
|
connection.get("users/#{Berkshelf.config.chef.node_name}") rescue nil
|
60
60
|
|
61
61
|
cookbooks.map do |cookbook|
|
62
|
+
|
63
|
+
compiled_metadata = cookbook.compile_metadata
|
64
|
+
cookbook.reload if compiled_metadata
|
65
|
+
cookbook_version = cookbook.cookbook_version
|
66
|
+
Berkshelf.log.debug " Uploading #{cookbook.cookbook_name}"
|
67
|
+
cookbook_version.freeze_version if options[:freeze]
|
68
|
+
|
69
|
+
# another two lines that are necessary for chef < 13.2 support (affects 11.x/12.x as well)
|
70
|
+
cookbook_version.metadata.maintainer "" if cookbook_version.metadata.maintainer.nil?
|
71
|
+
cookbook_version.metadata.maintainer_email "" if cookbook_version.metadata.maintainer_email.nil?
|
72
|
+
|
62
73
|
begin
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
Chef::CookbookUploader.new(
|
75
|
-
[ cookbook_version ],
|
76
|
-
force: options[:force],
|
77
|
-
concurrency: 1, # sadly
|
78
|
-
rest: connection,
|
79
|
-
skip_syntax_check: options[:skip_syntax_check]
|
80
|
-
).upload_cookbooks
|
81
|
-
Berkshelf.formatter.uploaded(cookbook, connection)
|
82
|
-
rescue Chef::Exceptions::CookbookFrozen
|
83
|
-
if options[:halt_on_frozen]
|
84
|
-
raise FrozenCookbook.new(cookbook)
|
85
|
-
end
|
86
|
-
|
87
|
-
Berkshelf.formatter.skipping(cookbook, connection)
|
88
|
-
end
|
89
|
-
ensure
|
90
|
-
if compiled_metadata
|
91
|
-
# this is necessary on windows to clean up the ruby object that was pointing at the file
|
92
|
-
# so that we can reliably delete it. windows is terrible.
|
93
|
-
GC.start
|
94
|
-
File.unlink(compiled_metadata)
|
74
|
+
Chef::CookbookUploader.new(
|
75
|
+
[ cookbook_version ],
|
76
|
+
force: options[:force],
|
77
|
+
concurrency: 1, # sadly
|
78
|
+
rest: connection,
|
79
|
+
skip_syntax_check: options[:skip_syntax_check]
|
80
|
+
).upload_cookbooks
|
81
|
+
Berkshelf.formatter.uploaded(cookbook, connection)
|
82
|
+
rescue Chef::Exceptions::CookbookFrozen
|
83
|
+
if options[:halt_on_frozen]
|
84
|
+
raise FrozenCookbook.new(cookbook)
|
95
85
|
end
|
86
|
+
|
87
|
+
Berkshelf.formatter.skipping(cookbook, connection)
|
96
88
|
end
|
89
|
+
ensure
|
90
|
+
if compiled_metadata
|
91
|
+
# this is necessary on windows to clean up the ruby object that was pointing at the file
|
92
|
+
# so that we can reliably delete it. windows is terrible.
|
93
|
+
GC.start
|
94
|
+
File.unlink(compiled_metadata)
|
95
|
+
end
|
96
|
+
|
97
97
|
end
|
98
98
|
end
|
99
99
|
end
|
data/lib/berkshelf/validator.rb
CHANGED
@@ -22,15 +22,9 @@ module Berkshelf
|
|
22
22
|
# the Cookbook(s) to validate
|
23
23
|
def validate_files(cookbooks)
|
24
24
|
Array(cookbooks).each do |cookbook|
|
25
|
-
|
25
|
+
base, name = Pathname.new(cookbook.path.to_s).split
|
26
26
|
|
27
|
-
files = Dir.
|
28
|
-
Dir.glob(File.join("**", "*.rb")).select do |f|
|
29
|
-
f = File.join(path, f)
|
30
|
-
parent = Pathname.new(path).dirname.to_s
|
31
|
-
f.gsub(parent, "") =~ /[[:space:]]/
|
32
|
-
end
|
33
|
-
end
|
27
|
+
files = Dir.glob("#{name}/**/*.rb", base: base.to_s).select { |f| f =~ /[[:space:]]/ }
|
34
28
|
|
35
29
|
raise InvalidCookbookFiles.new(cookbook, files) unless files.empty?
|
36
30
|
end
|
data/lib/berkshelf/version.rb
CHANGED
data/lib/berkshelf/visualizer.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
data/spec/support/git.rb
CHANGED
@@ -84,26 +84,26 @@ module Berkshelf
|
|
84
84
|
|
85
85
|
private
|
86
86
|
|
87
|
-
|
88
|
-
|
89
|
-
|
87
|
+
# The path to store the local git clones.
|
88
|
+
#
|
89
|
+
# @return [Pathname]
|
90
90
|
def clones
|
91
91
|
ensure_and_return(tmp_path.join("clones"))
|
92
92
|
end
|
93
93
|
|
94
|
-
|
95
|
-
|
96
|
-
|
94
|
+
# The path to store the git remotes.
|
95
|
+
#
|
96
|
+
# @return [Pathname]
|
97
97
|
def remotes
|
98
98
|
ensure_and_return(tmp_path.join("remotes"))
|
99
99
|
end
|
100
100
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
101
|
+
# Generate a cookbook by the given name.
|
102
|
+
#
|
103
|
+
# @param [#to_s] name
|
104
|
+
# the name of the cookbook to create
|
105
|
+
# @param [Hash] options
|
106
|
+
# the list ooptions to pass to the generator
|
107
107
|
def generate_git_cookbook(name, options = {})
|
108
108
|
options = {
|
109
109
|
skip_vagrant: true,
|
@@ -114,12 +114,12 @@ module Berkshelf
|
|
114
114
|
Berkshelf::Cli.new.invoke(:cookbook, [name.to_s], options)
|
115
115
|
end
|
116
116
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
117
|
+
# Make sure the given path exists and return the path
|
118
|
+
#
|
119
|
+
# @param [#to_s] path
|
120
|
+
# the path to create and return
|
121
|
+
#
|
122
|
+
# @return [Pathname]
|
123
123
|
def ensure_and_return(path)
|
124
124
|
FileUtils.mkdir(path) unless File.exist?(path)
|
125
125
|
Pathname.new(path).expand_path
|
@@ -50,10 +50,10 @@ module Berkshelf
|
|
50
50
|
|
51
51
|
private
|
52
52
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
53
|
+
# This is the magical "reset" function that gives us a clean working
|
54
|
+
# directory on each run.
|
55
|
+
#
|
56
|
+
# @return [nil]
|
57
57
|
def reload_configs
|
58
58
|
Berkshelf.chef_config = chef_config
|
59
59
|
|