chef-dk 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/chef-dk/authenticated_http.rb +40 -0
  4. data/lib/chef-dk/chef_runner.rb +5 -0
  5. data/lib/chef-dk/command/exec.rb +4 -1
  6. data/lib/chef-dk/command/generate.rb +11 -0
  7. data/lib/chef-dk/command/generator_commands.rb +20 -365
  8. data/lib/chef-dk/command/generator_commands/app.rb +99 -0
  9. data/lib/chef-dk/command/generator_commands/attribute.rb +37 -0
  10. data/lib/chef-dk/command/generator_commands/base.rb +76 -0
  11. data/lib/chef-dk/command/generator_commands/cookbook.rb +100 -0
  12. data/lib/chef-dk/command/generator_commands/cookbook_code_file.rb +99 -0
  13. data/lib/chef-dk/command/generator_commands/cookbook_file.rb +45 -0
  14. data/lib/chef-dk/command/generator_commands/lwrp.rb +36 -0
  15. data/lib/chef-dk/command/generator_commands/recipe.rb +36 -0
  16. data/lib/chef-dk/command/generator_commands/repo.rb +96 -0
  17. data/lib/chef-dk/command/generator_commands/template.rb +45 -0
  18. data/lib/chef-dk/command/verify.rb +28 -0
  19. data/lib/chef-dk/component_test.rb +16 -3
  20. data/lib/chef-dk/cookbook_omnifetch.rb +2 -0
  21. data/lib/chef-dk/cookbook_profiler/identifiers.rb +3 -15
  22. data/lib/chef-dk/exceptions.rb +15 -0
  23. data/lib/chef-dk/generator.rb +102 -25
  24. data/lib/chef-dk/policyfile/community_cookbook_source.rb +0 -7
  25. data/lib/chef-dk/policyfile/{cookbook_spec.rb → cookbook_location_specification.rb} +35 -6
  26. data/lib/chef-dk/policyfile/cookbook_locks.rb +305 -0
  27. data/lib/chef-dk/policyfile/dsl.rb +26 -12
  28. data/lib/chef-dk/policyfile/read_cookbook_for_compat_mode_upload.rb +70 -0
  29. data/lib/chef-dk/policyfile/solution_dependencies.rb +204 -0
  30. data/lib/chef-dk/policyfile/storage_config.rb +77 -0
  31. data/lib/chef-dk/policyfile/uploader.rb +110 -0
  32. data/lib/chef-dk/policyfile_compiler.rb +59 -29
  33. data/lib/chef-dk/policyfile_lock.rb +104 -160
  34. data/lib/chef-dk/skeletons/code_generator/files/default/Berksfile +1 -1
  35. data/lib/chef-dk/skeletons/code_generator/files/default/chefignore +0 -1
  36. data/lib/chef-dk/skeletons/code_generator/files/default/repo/README.md +66 -0
  37. data/lib/chef-dk/skeletons/code_generator/files/default/repo/Rakefile +65 -0
  38. data/lib/chef-dk/skeletons/code_generator/files/default/repo/certificates/README.md +19 -0
  39. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/README-policy.md +9 -0
  40. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/README.md +54 -0
  41. data/lib/chef-dk/skeletons/code_generator/files/default/repo/data_bags/README.md +63 -0
  42. data/lib/chef-dk/skeletons/code_generator/files/default/repo/environments/README.md +5 -0
  43. data/lib/chef-dk/skeletons/code_generator/files/default/repo/roles/README.md +16 -0
  44. data/lib/chef-dk/skeletons/code_generator/recipes/cookbook.rb +7 -1
  45. data/lib/chef-dk/skeletons/code_generator/recipes/repo.rb +62 -0
  46. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.all_rights.erb +3 -0
  47. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.apache2.erb +201 -0
  48. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv2.erb +339 -0
  49. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv3.erb +674 -0
  50. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.mit.erb +21 -0
  51. data/lib/chef-dk/skeletons/code_generator/templates/default/default_recipe.rb.erb +1 -4
  52. data/lib/chef-dk/skeletons/code_generator/templates/default/metadata.rb.erb +3 -3
  53. data/lib/chef-dk/skeletons/code_generator/templates/default/repo/config/rake.rb.erb +38 -0
  54. data/lib/chef-dk/skeletons/code_generator/templates/default/repo/gitignore.erb +11 -0
  55. data/lib/chef-dk/version.rb +1 -1
  56. data/spec/shared/a_file_generator.rb +121 -0
  57. data/spec/shared/a_generated_file.rb +12 -0
  58. data/spec/shared/fixture_cookbook_checksums.rb +47 -0
  59. data/spec/spec_helper.rb +4 -2
  60. data/spec/unit/chef_runner_spec.rb +12 -5
  61. data/spec/unit/cli_spec.rb +4 -4
  62. data/spec/unit/command/base_spec.rb +1 -1
  63. data/spec/unit/command/exec_spec.rb +37 -27
  64. data/spec/unit/command/generate_spec.rb +3 -3
  65. data/spec/unit/command/generator_commands/app_spec.rb +131 -0
  66. data/spec/unit/command/generator_commands/attribute_spec.rb +32 -0
  67. data/spec/unit/command/generator_commands/cookbook_file_spec.rb +32 -0
  68. data/spec/unit/command/generator_commands/cookbook_spec.rb +205 -0
  69. data/spec/unit/command/generator_commands/lwrp_spec.rb +32 -0
  70. data/spec/unit/command/generator_commands/recipe_spec.rb +32 -0
  71. data/spec/unit/command/generator_commands/repo_spec.rb +287 -0
  72. data/spec/unit/command/generator_commands/template_spec.rb +32 -0
  73. data/spec/unit/command/shell_init_spec.rb +4 -4
  74. data/spec/unit/command/verify_spec.rb +9 -9
  75. data/spec/unit/commands_map_spec.rb +1 -1
  76. data/spec/unit/component_test_spec.rb +3 -3
  77. data/spec/unit/cookbook_profiler/git_spec.rb +7 -7
  78. data/spec/unit/cookbook_profiler/identifiers_spec.rb +12 -8
  79. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/Berksfile +1 -1
  80. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/Berksfile +1 -1
  81. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/Berksfile +1 -1
  82. data/spec/unit/fixtures/example_cookbook/Berksfile +1 -1
  83. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/README.md +4 -0
  84. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/chefignore +96 -0
  85. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/metadata.rb +8 -0
  86. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/recipes/default.rb +8 -0
  87. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/Berksfile +1 -1
  88. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -0
  89. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -0
  90. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -0
  91. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -0
  92. data/spec/unit/generator_spec.rb +120 -0
  93. data/spec/unit/policyfile/{cookbook_spec_spec.rb → cookbook_location_specification_spec.rb} +83 -38
  94. data/spec/unit/policyfile/cookbook_locks_spec.rb +354 -0
  95. data/spec/unit/policyfile/read_cookbook_for_compat_mode_upload_spec.rb +85 -0
  96. data/spec/unit/policyfile/solution_dependencies_spec.rb +145 -0
  97. data/spec/unit/policyfile/storage_config_spec.rb +98 -0
  98. data/spec/unit/policyfile/uploader_spec.rb +292 -0
  99. data/spec/unit/policyfile_demands_spec.rb +177 -24
  100. data/spec/unit/policyfile_evaluation_spec.rb +40 -12
  101. data/spec/unit/{policyfile_builder_spec.rb → policyfile_lock_build_spec.rb} +179 -64
  102. data/spec/unit/policyfile_lock_install_spec.rb +138 -0
  103. data/spec/unit/policyfile_lock_validation_spec.rb +610 -0
  104. metadata +103 -59
  105. data/spec/unit/command/generator_commands_spec.rb +0 -504
@@ -18,7 +18,7 @@
18
18
  require 'forwardable'
19
19
 
20
20
  require 'solve'
21
- require 'chef/run_list/run_list_item'
21
+ require 'chef/run_list'
22
22
 
23
23
  require 'chef-dk/policyfile/dsl'
24
24
  require 'chef-dk/policyfile_lock'
@@ -40,16 +40,19 @@ module ChefDK
40
40
  compiler
41
41
  end
42
42
 
43
+ def_delegator :@dsl, :name
43
44
  def_delegator :@dsl, :run_list
44
45
  def_delegator :@dsl, :errors
45
46
  def_delegator :@dsl, :default_source
46
- def_delegator :@dsl, :policyfile_cookbook_specs
47
+ def_delegator :@dsl, :cookbook_location_specs
47
48
 
48
49
  attr_reader :dsl
50
+ attr_reader :storage_config
49
51
 
50
52
  def initialize
51
- @dsl = Policyfile::DSL.new
52
- @artifact_server_cookbook_specs = {}
53
+ @storage_config = Policyfile::StorageConfig.new
54
+ @dsl = Policyfile::DSL.new(storage_config)
55
+ @artifact_server_cookbook_location_specs = {}
53
56
  end
54
57
 
55
58
  def error!
@@ -58,23 +61,29 @@ module ChefDK
58
61
  end
59
62
  end
60
63
 
61
- def cookbook_spec_for(cookbook_name)
62
- policyfile_cookbook_specs[cookbook_name]
64
+ def cookbook_location_spec_for(cookbook_name)
65
+ cookbook_location_specs[cookbook_name]
63
66
  end
64
67
 
65
68
  def expanded_run_list
66
- run_list
69
+ # doesn't support roles yet...
70
+ Chef::RunList.new(*run_list)
71
+ end
72
+
73
+ # copy of the expanded_run_list, properly formatted for use in a lockfile
74
+ def normalized_run_list
75
+ expanded_run_list.map { |i| normalize_recipe(i) }
67
76
  end
68
77
 
69
78
  def lock
70
- @policyfile_lock ||= PolicyfileLock.build_from_compiler(self, cache_path: cache_path)
79
+ @policyfile_lock ||= PolicyfileLock.build_from_compiler(self, storage_config)
71
80
  end
72
81
 
73
82
  def install
74
83
  ensure_cache_dir_exists
75
84
 
76
85
  graph_solution.each do |cookbook_name, version|
77
- spec = cookbook_spec_for(cookbook_name)
86
+ spec = cookbook_location_spec_for(cookbook_name)
78
87
  if spec.nil? or !spec.version_fixed?
79
88
  spec = create_spec_for_cookbook(cookbook_name, version)
80
89
  spec.ensure_cached
@@ -84,17 +93,17 @@ module ChefDK
84
93
 
85
94
  def create_spec_for_cookbook(cookbook_name, version)
86
95
  source_options = default_source.source_options_for(cookbook_name, version)
87
- spec = Policyfile::CookbookSpec.new(cookbook_name, "= #{version}", source_options, dsl)
88
- @artifact_server_cookbook_specs[cookbook_name] = spec
96
+ spec = Policyfile::CookbookLocationSpecification.new(cookbook_name, "= #{version}", source_options, storage_config)
97
+ @artifact_server_cookbook_location_specs[cookbook_name] = spec
89
98
  end
90
99
 
91
- def all_cookbook_specs
92
- # in the installation proces, we create "artifact_server_cookbook_specs"
100
+ def all_cookbook_location_specs
101
+ # in the installation proces, we create "artifact_server_cookbook_location_specs"
93
102
  # for any cookbook that isn't sourced from a single-version source (e.g.,
94
103
  # path and git only support one version at a time), but we might have
95
104
  # specs for them to track additional version constraint demands. Merging
96
- # in this order ensures the artifact_server_cookbook_specs "win".
97
- policyfile_cookbook_specs.merge(@artifact_server_cookbook_specs)
105
+ # in this order ensures the artifact_server_cookbook_location_specs "win".
106
+ cookbook_location_specs.merge(@artifact_server_cookbook_location_specs)
98
107
  end
99
108
 
100
109
  ##
@@ -120,9 +129,23 @@ module ChefDK
120
129
  end
121
130
  end
122
131
 
132
+ def solution_dependencies
133
+ solution_deps = Policyfile::SolutionDependencies.new
134
+
135
+ all_cookbook_location_specs.each do |name, spec|
136
+ solution_deps.add_policyfile_dep(name, spec.version_constraint)
137
+ end
138
+
139
+ graph_solution.each do |name, version|
140
+ transitive_deps = artifacts_graph[name][version]
141
+ solution_deps.add_cookbook_dep(name, version, transitive_deps)
142
+ end
143
+ solution_deps
144
+ end
145
+
123
146
  def graph_demands
124
147
  cookbooks_for_demands.map do |cookbook_name|
125
- spec = cookbook_spec_for(cookbook_name)
148
+ spec = cookbook_location_spec_for(cookbook_name)
126
149
  if spec.nil?
127
150
  [ cookbook_name, DEFAULT_DEMAND_CONSTRAINT ]
128
151
  elsif spec.version_fixed?
@@ -145,9 +168,9 @@ module ChefDK
145
168
  # version number. To accomodate this, the local_artifacts_graph should be
146
169
  # merged over the upstream's artifacts graph.
147
170
  def local_artifacts_graph
148
- policyfile_cookbook_specs.inject({}) do |local_artifacts, (cookbook_name, cookbook_spec)|
149
- if cookbook_spec.version_fixed?
150
- local_artifacts[cookbook_name] = { cookbook_spec.version => cookbook_spec.dependencies }
171
+ cookbook_location_specs.inject({}) do |local_artifacts, (cookbook_name, cookbook_location_spec)|
172
+ if cookbook_location_spec.version_fixed?
173
+ local_artifacts[cookbook_name] = { cookbook_location_spec.version => cookbook_location_spec.dependencies }
151
174
  end
152
175
  local_artifacts
153
176
  end
@@ -158,8 +181,8 @@ module ChefDK
158
181
  end
159
182
 
160
183
  def version_constraint_for(cookbook_name)
161
- if (cookbook_spec = cookbook_spec_for(cookbook_name)) and cookbook_spec.version_fixed?
162
- version = cookbook_spec.version
184
+ if (cookbook_location_spec = cookbook_location_spec_for(cookbook_name)) and cookbook_location_spec.version_fixed?
185
+ version = cookbook_location_spec.version
163
186
  "= #{version}"
164
187
  else
165
188
  DEFAULT_DEMAND_CONSTRAINT
@@ -167,15 +190,16 @@ module ChefDK
167
190
  end
168
191
 
169
192
  def cookbook_version_fixed?(cookbook_name)
170
- if cookbook_spec = cookbook_spec_for(cookbook_name)
171
- cookbook_spec.version_fixed?
193
+ if cookbook_location_spec = cookbook_location_spec_for(cookbook_name)
194
+ cookbook_location_spec.version_fixed?
172
195
  else
173
196
  false
174
197
  end
175
198
  end
176
199
 
177
200
  def cookbooks_in_run_list
178
- run_list.map {|item_spec| Chef::RunList::RunListItem.new(item_spec).name }
201
+ recipes = expanded_run_list.map {|recipe| recipe.name }
202
+ recipes.map { |r| r[/^([^:]+)/, 1] }
179
203
  end
180
204
 
181
205
  def build
@@ -184,21 +208,28 @@ module ChefDK
184
208
  end
185
209
 
186
210
  def evaluate_policyfile(policyfile_string, policyfile_filename)
187
- @dsl.eval_policyfile(policyfile_string, policyfile_filename)
211
+ storage_config.use_policyfile(policyfile_filename)
212
+ @dsl.eval_policyfile(policyfile_string)
188
213
  self
189
214
  end
190
215
 
191
216
  private
192
217
 
218
+ def normalize_recipe(run_list_item)
219
+ name = run_list_item.name
220
+ name = "#{name}::default" unless name.include?("::")
221
+ "recipe[#{name}]"
222
+ end
223
+
193
224
  def cookbooks_for_demands
194
- (cookbooks_in_run_list + policyfile_cookbook_specs.keys).uniq
225
+ (cookbooks_in_run_list + cookbook_location_specs.keys).uniq
195
226
  end
196
227
 
197
228
  def cache_fixed_version_cookbooks
198
229
  ensure_cache_dir_exists
199
230
 
200
- policyfile_cookbook_specs.each do |_cookbook_name, cookbook_spec|
201
- cookbook_spec.ensure_cached if cookbook_spec.version_fixed?
231
+ cookbook_location_specs.each do |_cookbook_name, cookbook_location_spec|
232
+ cookbook_location_spec.ensure_cached if cookbook_location_spec.version_fixed?
202
233
  end
203
234
  end
204
235
 
@@ -212,6 +243,5 @@ module ChefDK
212
243
  CookbookOmnifetch.storage_path
213
244
  end
214
245
 
215
-
216
246
  end
217
247
  end
@@ -15,229 +15,173 @@
15
15
  # limitations under the License.
16
16
  #
17
17
 
18
- require 'chef-dk/cookbook_profiler/identifiers'
19
- require 'chef-dk/cookbook_profiler/null_scm'
20
- require 'chef-dk/cookbook_profiler/git'
18
+ require 'chef-dk/policyfile/storage_config'
19
+ require 'chef-dk/policyfile/cookbook_locks'
20
+ require 'chef-dk/policyfile/solution_dependencies'
21
21
 
22
22
  module ChefDK
23
23
  class PolicyfileLock
24
24
 
25
- # CachedCookbook objects represent a cookbook that has been fetched from an
26
- # upstream canonical source and stored (presumed unmodified).
27
- class CachedCookbook
28
-
29
- # The cookbook name (without any version or other info suffixed)
30
- attr_reader :name
31
-
32
- # The directory name in the cookbook cache where the cookbook is stored.
33
- # By convention, this should be the name of the cookbook followed by a
34
- # hyphen and then some sort of version identifier (depending on the
35
- # cookbook source).
36
- attr_accessor :cache_key
37
-
38
- # A URI pointing to the canonical source of the cookbook.
39
- attr_accessor :origin
40
-
41
- # A string that uniquely identifies the cookbook version. If not
42
- # explicitly set, an identifier is generated based on the cookbook's
43
- # content.
44
- attr_writer :identifier
45
-
46
- # A string in "X.Y.Z" version number format that uniquely identifies the
47
- # cookbook version. This is for compatibility with Chef Server 11.x,
48
- # where cookbooks are stored by x.y.z version numbers.
49
- attr_writer :dotted_decimal_identifier
50
-
51
- # The root of the cookbook cache.
52
- attr_reader :cache_path
53
-
54
- def initialize(name, cache_path)
55
- @name = name
56
- @cache_path = cache_path
57
- @origin = nil
58
- @cache_key = nil
59
- @identifier = nil
60
- @dotted_decimal_identifier = nil
61
- end
62
-
63
- def cookbook_path
64
- File.join(cache_path, cache_key)
65
- end
66
-
67
- def identifier
68
- @identifier || identifiers.content_identifier
69
- end
70
-
71
- def dotted_decimal_identifier
72
- @dotted_decimal_identifier || identifiers.dotted_decimal_identifier
73
- end
74
-
75
- def to_lock
76
- validate!
77
- {
78
- "version" => identifiers.semver_version,
79
- "identifier" => identifier,
80
- "dotted_decimal_identifier" => dotted_decimal_identifier,
81
- "cache_key" => cache_key,
82
- "origin" => origin
83
- }
84
- end
85
-
86
- def identifiers
87
- @identifiers ||= CookbookProfiler::Identifiers.new(cookbook_path)
88
- end
89
-
90
- def validate!
91
- unless File.exist?(cookbook_path)
92
- raise CachedCookbookNotFound, "Cookbook `#{name}' not found at expected cache location `#{cookbook_path}'"
93
- end
94
- end
95
-
96
- end
97
-
98
- # LocalCookbook objects represent cookbooks that are sourced from the local
99
- # filesystem and are assumed to be under active development.
100
- class LocalCookbook
101
-
102
- # A relative or absolute path to the cookbook. If a relative path is
103
- # given, it is resolved relative to #relative_paths_root
104
- attr_accessor :source
105
-
106
- # A string that uniquely identifies the cookbook version. If not
107
- # explicitly set, an identifier is generated based on the cookbook's
108
- # content.
109
- attr_writer :identifier
110
-
111
- # A string in "X.Y.Z" version number format that uniquely identifies the
112
- # cookbook version. This is for compatibility with Chef Server 11.x,
113
- # where cookbooks are stored by x.y.z version numbers.
114
- attr_writer :dotted_decimal_identifier
115
-
116
- # The root path from which source is expanded.
117
- attr_accessor :relative_paths_root
118
-
119
- def initialize(name, relative_paths_root)
120
- @name = name
121
- @identifier = nil
122
- @relative_paths_root = relative_paths_root
123
- end
124
-
125
- def cookbook_path
126
- File.expand_path(source, relative_paths_root)
127
- end
128
-
129
- def scm_profiler
130
- if File.exist?(File.join(cookbook_path, ".git"))
131
- CookbookProfiler::Git.new(cookbook_path)
132
- else
133
- CookbookProfiler::NullSCM.new(cookbook_path)
134
- end
135
- end
136
-
137
- def identifier
138
- @identifier || identifiers.content_identifier
139
- end
140
-
141
- def dotted_decimal_identifier
142
- @dotted_decimal_identifier || identifiers.dotted_decimal_identifier
143
- end
144
-
145
- def to_lock
146
-
147
- {
148
- "version" => identifiers.semver_version,
149
- "identifier" => identifier,
150
- "dotted_decimal_identifier" => dotted_decimal_identifier,
151
- "source" => source,
152
- "cache_key" => nil,
153
- "scm_info" => scm_profiler.profile_data
154
- }
155
- end
156
25
 
157
- def identifiers
158
- @identifiers ||= CookbookProfiler::Identifiers.new(cookbook_path)
159
- end
160
-
161
- end
162
-
163
- def self.build(options = {})
164
- lock = new(options)
26
+ def self.build(storage_config)
27
+ lock = new(storage_config)
165
28
  yield lock
166
29
  lock
167
30
  end
168
31
 
169
- def self.build_from_compiler(compiler, options = {})
170
- lock = new(options)
32
+ def self.build_from_compiler(compiler, storage_config)
33
+ lock = new(storage_config)
171
34
  lock.build_from_compiler(compiler)
172
35
  lock
173
36
  end
174
37
 
38
+ include Policyfile::StorageConfigDelegation
39
+
175
40
  attr_accessor :name
176
41
  attr_accessor :run_list
177
42
 
43
+ attr_reader :solution_dependencies
44
+
45
+ attr_reader :storage_config
46
+
178
47
  attr_reader :cookbook_locks
179
- attr_reader :cache_path
180
- attr_reader :relative_paths_root
181
48
 
182
- def initialize(options = {})
49
+ def initialize(storage_config)
183
50
  @name = nil
184
51
  @run_list = []
185
52
  @cookbook_locks = {}
186
53
  @relative_paths_root = Dir.pwd
187
- handle_options(options)
54
+ @storage_config = storage_config
55
+
56
+ @solution_dependencies = Policyfile::SolutionDependencies.new
57
+ end
58
+
59
+ def lock_data_for(cookbook_name)
60
+ @cookbook_locks[cookbook_name]
188
61
  end
189
62
 
190
63
  def cached_cookbook(name)
191
- cached_cookbook = CachedCookbook.new(name, cache_path)
192
- yield cached_cookbook
64
+ cached_cookbook = Policyfile::CachedCookbook.new(name, storage_config)
65
+ yield cached_cookbook if block_given?
193
66
  @cookbook_locks[name] = cached_cookbook
194
67
  end
195
68
 
196
69
  def local_cookbook(name)
197
- local_cookbook = LocalCookbook.new(name, relative_paths_root)
198
- yield local_cookbook
70
+ local_cookbook = Policyfile::LocalCookbook.new(name, storage_config)
71
+ yield local_cookbook if block_given?
199
72
  @cookbook_locks[name] = local_cookbook
200
73
  end
201
74
 
75
+ def dependencies
76
+ yield solution_dependencies
77
+ end
78
+
202
79
  def to_lock
203
80
  {}.tap do |lock|
204
81
  lock["name"] = name
205
82
  lock["run_list"] = run_list
206
83
  lock["cookbook_locks"] = cookbook_locks_for_lockfile
84
+ lock["solution_dependencies"] = solution_dependencies.to_lock
207
85
  end
208
86
  end
209
87
 
210
88
  def cookbook_locks_for_lockfile
211
- cookbook_locks.inject({}) do |locks_map, (name, cookbook_spec)|
212
- locks_map[name] = cookbook_spec.to_lock
89
+ cookbook_locks.inject({}) do |locks_map, (name, location_spec)|
90
+ location_spec.validate!
91
+ location_spec.gather_profile_data
92
+ locks_map[name] = location_spec.to_lock
213
93
  locks_map
214
94
  end
215
95
  end
216
96
 
97
+ def validate_cookbooks!
98
+ cookbook_locks.each do |name, cookbook_lock|
99
+ cookbook_lock.validate!
100
+ cookbook_lock.refresh!
101
+ end
102
+
103
+ # Check that versions and dependencies are still valid. First we need to
104
+ # refresh the dependency info for everything that has changed, then we
105
+ # check that the new versions and dependencies are valid for the working
106
+ # set of cookbooks. We can't do this in a single loop because the user
107
+ # may have modified two cookbooks such that the versions and constraints
108
+ # are only valid when both changes are considered together.
109
+ cookbook_locks.each do |name, cookbook_lock|
110
+ if cookbook_lock.updated?
111
+ solution_dependencies.update_cookbook_dep(name, cookbook_lock.version, cookbook_lock.dependencies)
112
+ end
113
+ end
114
+ cookbook_locks.each do |name, cookbook_lock|
115
+ if cookbook_lock.updated?
116
+ solution_dependencies.test_conflict!(cookbook_lock.name, cookbook_lock.version)
117
+ end
118
+ end
119
+
120
+ true
121
+ end
122
+
217
123
  def build_from_compiler(compiler)
218
- @run_list = compiler.expanded_run_list
124
+ @name = compiler.name
125
+
126
+ @run_list = compiler.normalized_run_list
219
127
 
220
- compiler.all_cookbook_specs.each do |cookbook_name, spec|
128
+ compiler.all_cookbook_location_specs.each do |cookbook_name, spec|
221
129
  if spec.mirrors_canonical_upstream?
222
130
  cached_cookbook(cookbook_name) do |cached_cb|
223
131
  cached_cb.cache_key = spec.cache_key
224
132
  cached_cb.origin = spec.uri
133
+ cached_cb.source_options = spec.source_options_for_lock
225
134
  end
226
135
  else
227
136
  local_cookbook(cookbook_name) do |local_cb|
228
137
  local_cb.source = spec.relative_path
229
- local_cb.relative_paths_root = spec.relative_paths_root
138
+ local_cb.source_options = spec.source_options_for_lock
230
139
  end
231
140
  end
232
141
  end
142
+
143
+ @solution_dependencies = compiler.solution_dependencies
144
+
145
+ self
146
+ end
147
+
148
+ def build_from_lock_data(lock_data)
149
+ @name = lock_data["name"]
150
+ @run_list = lock_data["run_list"]
151
+ lock_data["cookbook_locks"].each do |name, lock_info|
152
+ build_cookbook_lock_from_lock_data(name, lock_info)
153
+ end
154
+
155
+ s = Policyfile::SolutionDependencies.from_lock(lock_data["solution_dependencies"])
156
+ @solution_dependencies = s
233
157
  self
234
158
  end
235
159
 
160
+ def install_cookbooks
161
+ # note: duplicates PolicyfileCompiler#ensure_cache_dir_exists
162
+ ensure_cache_dir_exists
163
+
164
+ cookbook_locks.each do |cookbook_name, cookbook_lock|
165
+ cookbook_lock.install_locked
166
+ end
167
+ end
168
+
169
+ def ensure_cache_dir_exists
170
+ # note: duplicates PolicyfileCompiler#ensure_cache_dir_exists
171
+ unless File.exist?(cache_path)
172
+ FileUtils.mkdir_p(cache_path)
173
+ end
174
+ end
175
+
236
176
  private
237
177
 
238
- def handle_options(options)
239
- @cache_path = options[:cache_path]
240
- @relative_paths_root = options[:relative_paths_root] if options.key?(:relative_paths_root)
178
+ def build_cookbook_lock_from_lock_data(name, lock_info)
179
+ if lock_info["cache_key"].nil?
180
+ local_cookbook(name).build_from_lock_data(lock_info)
181
+ else
182
+ cached_cookbook(name).build_from_lock_data(lock_info)
183
+ end
241
184
  end
185
+
242
186
  end
243
187
  end