chef-dk 0.2.0 → 0.2.1
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 +4 -4
- data/README.md +1 -1
- data/lib/chef-dk/authenticated_http.rb +40 -0
- data/lib/chef-dk/chef_runner.rb +5 -0
- data/lib/chef-dk/command/exec.rb +4 -1
- data/lib/chef-dk/command/generate.rb +11 -0
- data/lib/chef-dk/command/generator_commands.rb +20 -365
- data/lib/chef-dk/command/generator_commands/app.rb +99 -0
- data/lib/chef-dk/command/generator_commands/attribute.rb +37 -0
- data/lib/chef-dk/command/generator_commands/base.rb +76 -0
- data/lib/chef-dk/command/generator_commands/cookbook.rb +100 -0
- data/lib/chef-dk/command/generator_commands/cookbook_code_file.rb +99 -0
- data/lib/chef-dk/command/generator_commands/cookbook_file.rb +45 -0
- data/lib/chef-dk/command/generator_commands/lwrp.rb +36 -0
- data/lib/chef-dk/command/generator_commands/recipe.rb +36 -0
- data/lib/chef-dk/command/generator_commands/repo.rb +96 -0
- data/lib/chef-dk/command/generator_commands/template.rb +45 -0
- data/lib/chef-dk/command/verify.rb +28 -0
- data/lib/chef-dk/component_test.rb +16 -3
- data/lib/chef-dk/cookbook_omnifetch.rb +2 -0
- data/lib/chef-dk/cookbook_profiler/identifiers.rb +3 -15
- data/lib/chef-dk/exceptions.rb +15 -0
- data/lib/chef-dk/generator.rb +102 -25
- data/lib/chef-dk/policyfile/community_cookbook_source.rb +0 -7
- data/lib/chef-dk/policyfile/{cookbook_spec.rb → cookbook_location_specification.rb} +35 -6
- data/lib/chef-dk/policyfile/cookbook_locks.rb +305 -0
- data/lib/chef-dk/policyfile/dsl.rb +26 -12
- data/lib/chef-dk/policyfile/read_cookbook_for_compat_mode_upload.rb +70 -0
- data/lib/chef-dk/policyfile/solution_dependencies.rb +204 -0
- data/lib/chef-dk/policyfile/storage_config.rb +77 -0
- data/lib/chef-dk/policyfile/uploader.rb +110 -0
- data/lib/chef-dk/policyfile_compiler.rb +59 -29
- data/lib/chef-dk/policyfile_lock.rb +104 -160
- data/lib/chef-dk/skeletons/code_generator/files/default/Berksfile +1 -1
- data/lib/chef-dk/skeletons/code_generator/files/default/chefignore +0 -1
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/README.md +66 -0
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/Rakefile +65 -0
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/certificates/README.md +19 -0
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/README-policy.md +9 -0
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/README.md +54 -0
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/data_bags/README.md +63 -0
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/environments/README.md +5 -0
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/roles/README.md +16 -0
- data/lib/chef-dk/skeletons/code_generator/recipes/cookbook.rb +7 -1
- data/lib/chef-dk/skeletons/code_generator/recipes/repo.rb +62 -0
- data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.all_rights.erb +3 -0
- data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.apache2.erb +201 -0
- data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv2.erb +339 -0
- data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv3.erb +674 -0
- data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.mit.erb +21 -0
- data/lib/chef-dk/skeletons/code_generator/templates/default/default_recipe.rb.erb +1 -4
- data/lib/chef-dk/skeletons/code_generator/templates/default/metadata.rb.erb +3 -3
- data/lib/chef-dk/skeletons/code_generator/templates/default/repo/config/rake.rb.erb +38 -0
- data/lib/chef-dk/skeletons/code_generator/templates/default/repo/gitignore.erb +11 -0
- data/lib/chef-dk/version.rb +1 -1
- data/spec/shared/a_file_generator.rb +121 -0
- data/spec/shared/a_generated_file.rb +12 -0
- data/spec/shared/fixture_cookbook_checksums.rb +47 -0
- data/spec/spec_helper.rb +4 -2
- data/spec/unit/chef_runner_spec.rb +12 -5
- data/spec/unit/cli_spec.rb +4 -4
- data/spec/unit/command/base_spec.rb +1 -1
- data/spec/unit/command/exec_spec.rb +37 -27
- data/spec/unit/command/generate_spec.rb +3 -3
- data/spec/unit/command/generator_commands/app_spec.rb +131 -0
- data/spec/unit/command/generator_commands/attribute_spec.rb +32 -0
- data/spec/unit/command/generator_commands/cookbook_file_spec.rb +32 -0
- data/spec/unit/command/generator_commands/cookbook_spec.rb +205 -0
- data/spec/unit/command/generator_commands/lwrp_spec.rb +32 -0
- data/spec/unit/command/generator_commands/recipe_spec.rb +32 -0
- data/spec/unit/command/generator_commands/repo_spec.rb +287 -0
- data/spec/unit/command/generator_commands/template_spec.rb +32 -0
- data/spec/unit/command/shell_init_spec.rb +4 -4
- data/spec/unit/command/verify_spec.rb +9 -9
- data/spec/unit/commands_map_spec.rb +1 -1
- data/spec/unit/component_test_spec.rb +3 -3
- data/spec/unit/cookbook_profiler/git_spec.rb +7 -7
- data/spec/unit/cookbook_profiler/identifiers_spec.rb +12 -8
- data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/Berksfile +1 -1
- data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/Berksfile +1 -1
- data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/Berksfile +1 -1
- data/spec/unit/fixtures/example_cookbook/Berksfile +1 -1
- data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/README.md +4 -0
- data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/chefignore +96 -0
- data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/metadata.rb +8 -0
- data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/recipes/default.rb +8 -0
- data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/Berksfile +1 -1
- data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -0
- data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -0
- data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -0
- data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -0
- data/spec/unit/generator_spec.rb +120 -0
- data/spec/unit/policyfile/{cookbook_spec_spec.rb → cookbook_location_specification_spec.rb} +83 -38
- data/spec/unit/policyfile/cookbook_locks_spec.rb +354 -0
- data/spec/unit/policyfile/read_cookbook_for_compat_mode_upload_spec.rb +85 -0
- data/spec/unit/policyfile/solution_dependencies_spec.rb +145 -0
- data/spec/unit/policyfile/storage_config_spec.rb +98 -0
- data/spec/unit/policyfile/uploader_spec.rb +292 -0
- data/spec/unit/policyfile_demands_spec.rb +177 -24
- data/spec/unit/policyfile_evaluation_spec.rb +40 -12
- data/spec/unit/{policyfile_builder_spec.rb → policyfile_lock_build_spec.rb} +179 -64
- data/spec/unit/policyfile_lock_install_spec.rb +138 -0
- data/spec/unit/policyfile_lock_validation_spec.rb +610 -0
- metadata +103 -59
- data/spec/unit/command/generator_commands_spec.rb +0 -504
|
@@ -18,13 +18,6 @@
|
|
|
18
18
|
require 'json'
|
|
19
19
|
require 'chef-dk/cookbook_omnifetch'
|
|
20
20
|
require 'chef-dk/exceptions'
|
|
21
|
-
# TODO: chef bug. Chef::HTTP::Simple needs to require this itself.
|
|
22
|
-
# Fixed in 2ed829e661f9a357fc9a8cdf316c84f077dad7f9 waiting for that to be
|
|
23
|
-
# released...
|
|
24
|
-
require 'tempfile'
|
|
25
|
-
require 'chef/platform/query_helpers' # should be handled by http/simple
|
|
26
|
-
require 'chef/http/cookie_manager' # should be handled by http/simple
|
|
27
|
-
require 'chef/http/validate_content_length' # should be handled by http/simple
|
|
28
21
|
require 'chef/http/simple'
|
|
29
22
|
|
|
30
23
|
# TODO: fix hardcoding
|
|
@@ -16,26 +16,41 @@
|
|
|
16
16
|
#
|
|
17
17
|
|
|
18
18
|
require 'semverse'
|
|
19
|
-
require '
|
|
19
|
+
require 'chef-dk/cookbook_omnifetch'
|
|
20
|
+
require 'chef-dk/policyfile/storage_config'
|
|
20
21
|
|
|
21
22
|
module ChefDK
|
|
22
23
|
module Policyfile
|
|
23
24
|
|
|
24
|
-
class
|
|
25
|
+
class CookbookLocationSpecification
|
|
26
|
+
|
|
27
|
+
#--
|
|
28
|
+
# Provides #relative_paths_root, which is required by CookbookOmnifetch
|
|
29
|
+
# API contract
|
|
30
|
+
include StorageConfigDelegation
|
|
25
31
|
|
|
26
32
|
SOURCE_TYPES = [:git, :github, :path, :artifactserver]
|
|
27
33
|
|
|
34
|
+
#--
|
|
35
|
+
# Required by CookbookOmnifetch API contract
|
|
28
36
|
attr_reader :version_constraint
|
|
37
|
+
|
|
38
|
+
#--
|
|
39
|
+
# Required by CookbookOmnifetch API contract
|
|
29
40
|
attr_reader :name
|
|
41
|
+
|
|
42
|
+
#--
|
|
43
|
+
# Required by CookbookOmnifetch API contract
|
|
30
44
|
attr_reader :source_options
|
|
31
45
|
attr_reader :source_type
|
|
46
|
+
attr_reader :storage_config
|
|
32
47
|
|
|
33
|
-
def initialize(name, version_constraint, source_options,
|
|
48
|
+
def initialize(name, version_constraint, source_options, storage_config)
|
|
34
49
|
@name = name
|
|
35
50
|
@version_constraint = Semverse::Constraint.new(version_constraint)
|
|
36
51
|
@source_options = source_options
|
|
37
|
-
@policyfile_filename = policyfile_filename
|
|
38
52
|
@source_type = SOURCE_TYPES.find { |type| source_options.key?(type) }
|
|
53
|
+
@storage_config = storage_config
|
|
39
54
|
end
|
|
40
55
|
|
|
41
56
|
def ==(other)
|
|
@@ -55,7 +70,20 @@ module ChefDK
|
|
|
55
70
|
end
|
|
56
71
|
end
|
|
57
72
|
|
|
73
|
+
def valid?
|
|
74
|
+
errors.empty?
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def errors
|
|
78
|
+
error_messages = []
|
|
79
|
+
if installer.nil?
|
|
80
|
+
error_messages << "Cookbook `#{name}' has invalid source options `#{source_options.inspect}'"
|
|
81
|
+
end
|
|
82
|
+
error_messages
|
|
83
|
+
end
|
|
84
|
+
|
|
58
85
|
def installer
|
|
86
|
+
# TODO: handle 'bad' return values here (invalid source_options, etc.)
|
|
59
87
|
@installer ||= CookbookOmnifetch.init(self, source_options)
|
|
60
88
|
end
|
|
61
89
|
|
|
@@ -84,11 +112,12 @@ module ChefDK
|
|
|
84
112
|
end
|
|
85
113
|
|
|
86
114
|
def cached_cookbook
|
|
115
|
+
# TODO: handle 'bad' return values here (cookbook not installed yet)
|
|
87
116
|
installer.cached_cookbook
|
|
88
117
|
end
|
|
89
118
|
|
|
90
|
-
def
|
|
91
|
-
|
|
119
|
+
def source_options_for_lock
|
|
120
|
+
installer.lock_data
|
|
92
121
|
end
|
|
93
122
|
|
|
94
123
|
end
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
|
|
2
|
+
require 'chef-dk/exceptions'
|
|
3
|
+
|
|
4
|
+
require 'chef-dk/cookbook_profiler/null_scm'
|
|
5
|
+
require 'chef-dk/cookbook_profiler/git'
|
|
6
|
+
|
|
7
|
+
require 'chef-dk/cookbook_profiler/identifiers'
|
|
8
|
+
require 'chef-dk/policyfile/storage_config'
|
|
9
|
+
|
|
10
|
+
require 'chef-dk/policyfile/cookbook_location_specification'
|
|
11
|
+
|
|
12
|
+
module ChefDK
|
|
13
|
+
|
|
14
|
+
module Policyfile
|
|
15
|
+
|
|
16
|
+
# Base class for CookbookLock implementations
|
|
17
|
+
class CookbookLock
|
|
18
|
+
|
|
19
|
+
include Policyfile::StorageConfigDelegation
|
|
20
|
+
|
|
21
|
+
# The cookbook name (without any version or other info suffixed)
|
|
22
|
+
attr_reader :name
|
|
23
|
+
|
|
24
|
+
# Options specifying the source and revision of this cookbook. These can
|
|
25
|
+
# be passed to a CookbookLocationSpecification to create an object that can install the
|
|
26
|
+
# same revision of the cookbook on another machine.
|
|
27
|
+
attr_accessor :source_options
|
|
28
|
+
|
|
29
|
+
# A string that uniquely identifies the cookbook version. If not
|
|
30
|
+
# explicitly set, an identifier is generated based on the cookbook's
|
|
31
|
+
# content.
|
|
32
|
+
attr_accessor :identifier
|
|
33
|
+
|
|
34
|
+
# A string in "X.Y.Z" version number format that uniquely identifies the
|
|
35
|
+
# cookbook version. This is for compatibility with Chef Server 11.x,
|
|
36
|
+
# where cookbooks are stored by x.y.z version numbers.
|
|
37
|
+
attr_accessor :dotted_decimal_identifier
|
|
38
|
+
|
|
39
|
+
attr_reader :storage_config
|
|
40
|
+
|
|
41
|
+
attr_accessor :version
|
|
42
|
+
|
|
43
|
+
def initialize(name, storage_config)
|
|
44
|
+
@name = name
|
|
45
|
+
@version = nil
|
|
46
|
+
@source_options = nil
|
|
47
|
+
@identifier = nil
|
|
48
|
+
@dotted_decimal_identifier = nil
|
|
49
|
+
@storage_config = storage_config
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def install_locked
|
|
53
|
+
cookbook_location_spec.ensure_cached
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def cookbook_location_spec
|
|
57
|
+
raise InvalidCookbookLockData, "Cannot create CookbookLocationSpecification for #{name} without version" if version.nil?
|
|
58
|
+
raise InvalidCookbookLockData, "Cannot create CookbookLocationSpecification for #{name} without source options" if source_options.nil?
|
|
59
|
+
@location_spec ||= CookbookLocationSpecification.new(name, "= #{version}", source_options, storage_config)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def dependencies
|
|
63
|
+
cookbook_location_spec.dependencies
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def gather_profile_data
|
|
67
|
+
@identifier ||= identifiers.content_identifier
|
|
68
|
+
@dotted_decimal_identifier ||= identifiers.dotted_decimal_identifier
|
|
69
|
+
@version ||= identifiers.semver_version
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def identifiers
|
|
73
|
+
@identifiers ||= CookbookProfiler::Identifiers.new(cookbook_version)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def cookbook_path
|
|
77
|
+
raise NotImplementedError, "#{self.class} must override #to_lock with a specific implementation"
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def to_lock
|
|
81
|
+
raise NotImplementedError, "#{self.class} must override #to_lock with a specific implementation"
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def build_from_lock_data(lock_data)
|
|
85
|
+
raise NotImplementedError, "#{self.class} must override #build_from_lock_data with a specific implementation"
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def validate!
|
|
89
|
+
raise NotImplementedError, "#{self.class} must override #validate! with a specific implementation"
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def refresh!
|
|
93
|
+
raise NotImplementedError, "#{self.class} must override #refresh! with a specific implementation"
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def updated?
|
|
97
|
+
false
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def identifier_updated?
|
|
101
|
+
false
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def version_updated?
|
|
105
|
+
false
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def symbolize_source_options_keys(source_options_from_json)
|
|
109
|
+
source_options_from_json ||= {}
|
|
110
|
+
source_options_from_json.inject({}) do |normalized_source_opts, (key, value)|
|
|
111
|
+
normalized_source_opts[key.to_sym] = value
|
|
112
|
+
normalized_source_opts
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def cookbook_version
|
|
117
|
+
@cookbook_version ||= cookbook_loader.cookbook_version
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def cookbook_loader
|
|
121
|
+
@cookbook_loader ||=
|
|
122
|
+
begin
|
|
123
|
+
loader = Chef::Cookbook::CookbookVersionLoader.new(cookbook_path, chefignore)
|
|
124
|
+
loader.load!
|
|
125
|
+
loader
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def chefignore
|
|
130
|
+
@chefignore ||= Chef::Cookbook::Chefignore.new(File.join(cookbook_path, "chefignore"))
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# CachedCookbook objects represent a cookbook that has been fetched from an
|
|
135
|
+
# upstream canonical source and stored (presumed unmodified).
|
|
136
|
+
class CachedCookbook < CookbookLock
|
|
137
|
+
|
|
138
|
+
# The directory name in the cookbook cache where the cookbook is stored.
|
|
139
|
+
# By convention, this should be the name of the cookbook followed by a
|
|
140
|
+
# hyphen and then some sort of version identifier (depending on the
|
|
141
|
+
# cookbook source).
|
|
142
|
+
attr_accessor :cache_key
|
|
143
|
+
|
|
144
|
+
# A URI pointing to the canonical source of the cookbook.
|
|
145
|
+
attr_accessor :origin
|
|
146
|
+
|
|
147
|
+
def initialize(name, storage_config)
|
|
148
|
+
@name = name
|
|
149
|
+
@version = nil
|
|
150
|
+
@origin = nil
|
|
151
|
+
@source_options = nil
|
|
152
|
+
@cache_key = nil
|
|
153
|
+
@identifier = nil
|
|
154
|
+
@dotted_decimal_identifier = nil
|
|
155
|
+
@storage_config = storage_config
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def cookbook_path
|
|
159
|
+
if cache_key.nil?
|
|
160
|
+
raise MissingCookbookLockData, "Cannot locate cached cookbook `#{name}' because the `cache_key' attribute is not set"
|
|
161
|
+
end
|
|
162
|
+
File.join(cache_path, cache_key)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def build_from_lock_data(lock_data)
|
|
166
|
+
@version = lock_data["version"]
|
|
167
|
+
@identifier = lock_data["identifier"]
|
|
168
|
+
@dotted_decimal_identifier = lock_data["dotted_decimal_identifier"]
|
|
169
|
+
@cache_key = lock_data["cache_key"]
|
|
170
|
+
@origin = lock_data["origin"]
|
|
171
|
+
@source_options = symbolize_source_options_keys(lock_data["source_options"])
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def to_lock
|
|
175
|
+
validate!
|
|
176
|
+
{
|
|
177
|
+
"version" => version,
|
|
178
|
+
"identifier" => identifier,
|
|
179
|
+
"dotted_decimal_identifier" => dotted_decimal_identifier,
|
|
180
|
+
"cache_key" => cache_key,
|
|
181
|
+
"origin" => origin,
|
|
182
|
+
"source_options" => source_options
|
|
183
|
+
}
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def validate!
|
|
187
|
+
if cache_key.nil?
|
|
188
|
+
raise CachedCookbookNotFound, "Cookbook `#{name}' does not have a `cache_key` set, cannot locate cookbook"
|
|
189
|
+
end
|
|
190
|
+
unless File.exist?(cookbook_path)
|
|
191
|
+
raise CachedCookbookNotFound, "Cookbook `#{name}' not found at expected cache location `#{cache_key}' (full path: `#{cookbook_path}')"
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# We do not expect the cookbook to get mutated out-of-band, so refreshing
|
|
196
|
+
# the data generally should have no affect. If the cookbook has been
|
|
197
|
+
# mutated, though, then a CachedCookbookModified exception is raised.
|
|
198
|
+
def refresh!
|
|
199
|
+
# This behavior fits better with the intent of the #validate! method,
|
|
200
|
+
# but we cannot check for modifications there because the user may be
|
|
201
|
+
# setting custom identifiers.
|
|
202
|
+
if @identifier and identifiers.content_identifier != @identifier
|
|
203
|
+
message = "Cached cookbook `#{name}' (#{version}) has been modified since the lockfile was generated. " +
|
|
204
|
+
"Cached cookbooks cannot be modified. (full path: `#{cookbook_path}')"
|
|
205
|
+
raise CachedCookbookModified, message
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# LocalCookbook objects represent cookbooks that are sourced from the local
|
|
212
|
+
# filesystem and are assumed to be under active development.
|
|
213
|
+
class LocalCookbook < CookbookLock
|
|
214
|
+
|
|
215
|
+
# A relative or absolute path to the cookbook. If a relative path is
|
|
216
|
+
# given, it is resolved relative to #relative_paths_root
|
|
217
|
+
attr_accessor :source
|
|
218
|
+
|
|
219
|
+
def initialize(name, storage_config)
|
|
220
|
+
@name = name
|
|
221
|
+
@identifier = nil
|
|
222
|
+
@storage_config = storage_config
|
|
223
|
+
|
|
224
|
+
@identifier_updated = false
|
|
225
|
+
@version_updated = false
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def cookbook_path
|
|
229
|
+
File.expand_path(source, relative_paths_root)
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def scm_profiler
|
|
233
|
+
if File.exist?(File.join(cookbook_path, ".git"))
|
|
234
|
+
CookbookProfiler::Git.new(cookbook_path)
|
|
235
|
+
else
|
|
236
|
+
CookbookProfiler::NullSCM.new(cookbook_path)
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def scm_info
|
|
241
|
+
scm_profiler.profile_data
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def to_lock
|
|
245
|
+
validate!
|
|
246
|
+
{
|
|
247
|
+
"version" => version,
|
|
248
|
+
"identifier" => identifier,
|
|
249
|
+
"dotted_decimal_identifier" => dotted_decimal_identifier,
|
|
250
|
+
"source" => source,
|
|
251
|
+
"cache_key" => nil,
|
|
252
|
+
"scm_info" => scm_info,
|
|
253
|
+
"source_options" => source_options
|
|
254
|
+
}
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
def build_from_lock_data(lock_data)
|
|
258
|
+
@version = lock_data["version"]
|
|
259
|
+
@identifier = lock_data["identifier"]
|
|
260
|
+
@dotted_decimal_identifier = lock_data["dotted_decimal_identifier"]
|
|
261
|
+
@source = lock_data["source"]
|
|
262
|
+
@source_options = symbolize_source_options_keys(lock_data["source_options"])
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
def validate!
|
|
266
|
+
if source.nil?
|
|
267
|
+
raise LocalCookbookNotFound, "Cookbook `#{name}' does not have a `source` set, cannot locate cookbook"
|
|
268
|
+
end
|
|
269
|
+
unless File.exist?(cookbook_path)
|
|
270
|
+
raise LocalCookbookNotFound, "Cookbook `#{name}' not found at path source `#{source}` (full path: `#{cookbook_path}')"
|
|
271
|
+
end
|
|
272
|
+
unless cookbook_version.name.to_s == name
|
|
273
|
+
msg = "The cookbook at path source `#{source}' is expected to be named `#{name}', but is now named `#{cookbook_version.name}' (full path: #{cookbook_path})"
|
|
274
|
+
raise MalformedCookbook, msg
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
def refresh!
|
|
279
|
+
old_identifier, old_version = @identifier, @version
|
|
280
|
+
@identifier, @dotted_decimal_identifier, @version = nil, nil, nil
|
|
281
|
+
gather_profile_data
|
|
282
|
+
if @identifier != old_identifier
|
|
283
|
+
@identifier_updated = true
|
|
284
|
+
end
|
|
285
|
+
if @version != old_version
|
|
286
|
+
@version_updated = true
|
|
287
|
+
end
|
|
288
|
+
self
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
def updated?
|
|
292
|
+
@identifier_updated || @version_updated
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
def version_updated?
|
|
296
|
+
@version_updated
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
def identifier_updated?
|
|
300
|
+
@identifier_updated
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
end
|
|
@@ -16,25 +16,38 @@
|
|
|
16
16
|
#
|
|
17
17
|
|
|
18
18
|
require 'chef-dk/policyfile/cookbook_sources'
|
|
19
|
-
require 'chef-dk/policyfile/
|
|
19
|
+
require 'chef-dk/policyfile/cookbook_location_specification'
|
|
20
|
+
require 'chef-dk/policyfile/storage_config'
|
|
20
21
|
|
|
21
22
|
module ChefDK
|
|
22
23
|
module Policyfile
|
|
23
24
|
class DSL
|
|
24
25
|
|
|
26
|
+
include StorageConfigDelegation
|
|
27
|
+
|
|
28
|
+
attr_writer :name
|
|
29
|
+
|
|
25
30
|
attr_reader :errors
|
|
26
31
|
attr_reader :run_list
|
|
27
32
|
attr_reader :default_source
|
|
28
|
-
attr_reader :
|
|
33
|
+
attr_reader :cookbook_location_specs
|
|
29
34
|
|
|
30
|
-
|
|
35
|
+
attr_reader :storage_config
|
|
31
36
|
|
|
32
|
-
def initialize
|
|
37
|
+
def initialize(storage_config)
|
|
38
|
+
@name = nil
|
|
33
39
|
@errors = []
|
|
34
40
|
@run_list = []
|
|
35
41
|
@default_source = NullCookbookSource.new
|
|
36
|
-
@
|
|
37
|
-
@
|
|
42
|
+
@cookbook_location_specs = {}
|
|
43
|
+
@storage_config = storage_config
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def name(name = nil)
|
|
47
|
+
unless name.nil?
|
|
48
|
+
@name = name
|
|
49
|
+
end
|
|
50
|
+
@name
|
|
38
51
|
end
|
|
39
52
|
|
|
40
53
|
def run_list(*run_list_items)
|
|
@@ -64,20 +77,21 @@ module ChefDK
|
|
|
64
77
|
end
|
|
65
78
|
|
|
66
79
|
constraint = version_and_source_opts.first || ">= 0.0.0"
|
|
67
|
-
spec =
|
|
80
|
+
spec = CookbookLocationSpecification.new(name, constraint, source_options, storage_config)
|
|
68
81
|
|
|
69
82
|
|
|
70
|
-
if existing_source = @
|
|
83
|
+
if existing_source = @cookbook_location_specs[name]
|
|
71
84
|
err = "Cookbook '#{name}' assigned to conflicting sources\n\n"
|
|
72
85
|
err << "Previous source: #{existing_source.source_options.inspect}\n"
|
|
73
86
|
err << "Conflicts with: #{source_options.inspect}\n"
|
|
74
87
|
@errors << err
|
|
75
88
|
else
|
|
76
|
-
@
|
|
89
|
+
@cookbook_location_specs[name] = spec
|
|
90
|
+
@errors += spec.errors
|
|
77
91
|
end
|
|
78
92
|
end
|
|
79
93
|
|
|
80
|
-
def eval_policyfile(policyfile_string
|
|
94
|
+
def eval_policyfile(policyfile_string)
|
|
81
95
|
@policyfile_filename = policyfile_filename
|
|
82
96
|
instance_eval(policyfile_string, policyfile_filename)
|
|
83
97
|
validate!
|
|
@@ -95,8 +109,8 @@ module ChefDK
|
|
|
95
109
|
error_message << " #{error_context(policyfile_string, policyfile_filename, e)}\n\n"
|
|
96
110
|
unless trace.empty?
|
|
97
111
|
error_message << " Backtrace:\n"
|
|
98
|
-
|
|
99
|
-
error_message << "\n"
|
|
112
|
+
# TODO: need a way to disable filtering
|
|
113
|
+
error_message << filtered_bt(policyfile_filename, e).inject("") { |formatted_trace, line| formatted_trace << " #{line}\n" }
|
|
100
114
|
end
|
|
101
115
|
@errors << error_message
|
|
102
116
|
end
|