chef-dk 0.2.1 → 0.3.0
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/CONTRIBUTING.md +2 -2
- data/README.md +25 -0
- data/lib/chef-dk/builtin_commands.rb +4 -0
- data/lib/chef-dk/cli.rb +46 -0
- data/lib/chef-dk/command/base.rb +4 -0
- data/lib/chef-dk/command/generator_commands/template.rb +2 -1
- data/lib/chef-dk/command/install.rb +105 -0
- data/lib/chef-dk/command/push.rb +123 -0
- data/lib/chef-dk/cookbook_profiler/identifiers.rb +5 -0
- data/lib/chef-dk/exceptions.rb +38 -0
- data/lib/chef-dk/generator.rb +16 -1
- data/lib/chef-dk/helpers.rb +1 -1
- data/lib/chef-dk/policyfile/cookbook_location_specification.rb +4 -0
- data/lib/chef-dk/policyfile/cookbook_locks.rb +73 -0
- data/lib/chef-dk/policyfile/reports/install.rb +70 -0
- data/lib/chef-dk/policyfile/reports/table_printer.rb +58 -0
- data/lib/chef-dk/policyfile/reports/upload.rb +70 -0
- data/lib/chef-dk/policyfile/solution_dependencies.rb +102 -8
- data/lib/chef-dk/policyfile/uploader.rb +37 -6
- data/lib/chef-dk/policyfile_compiler.rb +19 -5
- data/lib/chef-dk/policyfile_lock.rb +122 -9
- data/lib/chef-dk/policyfile_services/install.rb +131 -0
- data/lib/chef-dk/policyfile_services/push.rb +121 -0
- data/lib/chef-dk/skeletons/code_generator/recipes/cookbook.rb +6 -4
- data/lib/chef-dk/ui.rb +50 -0
- data/lib/chef-dk/version.rb +1 -1
- data/spec/shared/a_file_generator.rb +4 -1
- data/spec/test_helpers.rb +21 -0
- data/spec/unit/cli_spec.rb +100 -1
- data/spec/unit/command/base_spec.rb +23 -0
- data/spec/unit/command/exec_spec.rb +2 -2
- data/spec/unit/command/install_spec.rb +159 -0
- data/spec/unit/command/push_spec.rb +203 -0
- data/spec/unit/command/shell_init_spec.rb +1 -1
- data/spec/unit/policyfile/cookbook_location_specification_spec.rb +7 -0
- data/spec/unit/policyfile/cookbook_locks_spec.rb +13 -2
- data/spec/unit/policyfile/reports/install_spec.rb +115 -0
- data/spec/unit/policyfile/reports/upload_spec.rb +96 -0
- data/spec/unit/policyfile/solution_dependencies_spec.rb +1 -1
- data/spec/unit/policyfile/uploader_spec.rb +9 -12
- data/spec/unit/policyfile_lock_serialization_spec.rb +292 -0
- data/spec/unit/policyfile_services/install_spec.rb +170 -0
- data/spec/unit/policyfile_services/push_spec.rb +202 -0
- metadata +48 -6
@@ -18,24 +18,35 @@
|
|
18
18
|
require 'chef/cookbook_uploader'
|
19
19
|
require 'chef-dk/policyfile/read_cookbook_for_compat_mode_upload'
|
20
20
|
|
21
|
+
require 'chef-dk/ui'
|
22
|
+
require 'chef-dk/policyfile/reports/upload'
|
23
|
+
|
21
24
|
module ChefDK
|
22
25
|
module Policyfile
|
23
26
|
class Uploader
|
24
27
|
|
28
|
+
LockedCookbookForUpload = Struct.new(:cookbook, :lock)
|
29
|
+
|
25
30
|
COMPAT_MODE_DATA_BAG_NAME = "policyfiles".freeze
|
26
31
|
|
27
32
|
attr_reader :policyfile_lock
|
28
33
|
attr_reader :policy_group
|
29
34
|
attr_reader :http_client
|
35
|
+
attr_reader :ui
|
30
36
|
|
31
|
-
def initialize(policyfile_lock, policy_group, http_client: nil)
|
37
|
+
def initialize(policyfile_lock, policy_group, ui: nil, http_client: nil)
|
32
38
|
@policyfile_lock = policyfile_lock
|
33
39
|
@policy_group = policy_group
|
34
40
|
@http_client = http_client
|
41
|
+
@ui = ui || UI.null
|
42
|
+
|
43
|
+
@cookbook_versions_for_policy = nil
|
35
44
|
end
|
36
45
|
|
37
46
|
def upload
|
38
|
-
|
47
|
+
ui.msg("WARN: Uploading policy to policy group #{policy_group} in compatibility mode")
|
48
|
+
|
49
|
+
upload_cookbooks
|
39
50
|
data_bag_create
|
40
51
|
data_bag_item_create
|
41
52
|
end
|
@@ -63,6 +74,8 @@ module ChefDK
|
|
63
74
|
}
|
64
75
|
|
65
76
|
upload_lockfile_as_data_bag_item(policy_id, data_item)
|
77
|
+
ui.msg("Policy uploaded as data bag item #{COMPAT_MODE_DATA_BAG_NAME}/#{policy_id}")
|
78
|
+
true
|
66
79
|
end
|
67
80
|
|
68
81
|
def uploader
|
@@ -71,8 +84,10 @@ module ChefDK
|
|
71
84
|
end
|
72
85
|
|
73
86
|
def cookbook_versions_to_upload
|
74
|
-
cookbook_versions_for_policy.
|
75
|
-
|
87
|
+
cookbook_versions_for_policy.inject([]) do |versions_to_upload, cookbook_with_lock|
|
88
|
+
cb = cookbook_with_lock.cookbook
|
89
|
+
versions_to_upload << cb unless remote_already_has_cookbook?(cb)
|
90
|
+
versions_to_upload
|
76
91
|
end
|
77
92
|
end
|
78
93
|
|
@@ -91,14 +106,30 @@ module ChefDK
|
|
91
106
|
# An Array of Chef::CookbookVersion objects representing the full set that
|
92
107
|
# the policyfile lock requires.
|
93
108
|
def cookbook_versions_for_policy
|
109
|
+
return @cookbook_versions_for_policy if @cookbook_versions_for_policy
|
94
110
|
policyfile_lock.validate_cookbooks!
|
95
|
-
policyfile_lock.cookbook_locks.map do |name, lock|
|
96
|
-
ReadCookbookForCompatModeUpload.load(name, lock.dotted_decimal_identifier, lock.cookbook_path)
|
111
|
+
@cookbook_versions_for_policy = policyfile_lock.cookbook_locks.map do |name, lock|
|
112
|
+
cb = ReadCookbookForCompatModeUpload.load(name, lock.dotted_decimal_identifier, lock.cookbook_path)
|
113
|
+
LockedCookbookForUpload.new(cb, lock)
|
97
114
|
end
|
98
115
|
end
|
99
116
|
|
100
117
|
private
|
101
118
|
|
119
|
+
def upload_cookbooks
|
120
|
+
ui.msg("WARN: Uploading cookbooks using semver compat mode")
|
121
|
+
|
122
|
+
uploader.upload_cookbooks
|
123
|
+
|
124
|
+
reused_cbs, uploaded_cbs = cookbook_versions_for_policy.partition do |cb_with_lock|
|
125
|
+
remote_already_has_cookbook?(cb_with_lock.cookbook)
|
126
|
+
end
|
127
|
+
|
128
|
+
Reports::Upload.new(reused_cbs: reused_cbs, uploaded_cbs: uploaded_cbs, ui: ui).show
|
129
|
+
|
130
|
+
true
|
131
|
+
end
|
132
|
+
|
102
133
|
def upload_lockfile_as_data_bag_item(policy_id, data_item)
|
103
134
|
http_client.put("data/#{COMPAT_MODE_DATA_BAG_NAME}/#{policy_id}", data_item)
|
104
135
|
rescue Net::HTTPServerException => e
|
@@ -22,6 +22,8 @@ require 'chef/run_list'
|
|
22
22
|
|
23
23
|
require 'chef-dk/policyfile/dsl'
|
24
24
|
require 'chef-dk/policyfile_lock'
|
25
|
+
require 'chef-dk/ui'
|
26
|
+
require 'chef-dk/policyfile/reports/install'
|
25
27
|
|
26
28
|
module ChefDK
|
27
29
|
|
@@ -34,8 +36,8 @@ module ChefDK
|
|
34
36
|
# Cookbooks from these sources lock that cookbook to exactly one version
|
35
37
|
SOURCE_TYPES_WITH_FIXED_VERSIONS = [:git, :path].freeze
|
36
38
|
|
37
|
-
def self.evaluate(policyfile_string, policyfile_filename)
|
38
|
-
compiler = new
|
39
|
+
def self.evaluate(policyfile_string, policyfile_filename, ui: nil)
|
40
|
+
compiler = new(ui: ui)
|
39
41
|
compiler.evaluate_policyfile(policyfile_string, policyfile_filename)
|
40
42
|
compiler
|
41
43
|
end
|
@@ -48,11 +50,15 @@ module ChefDK
|
|
48
50
|
|
49
51
|
attr_reader :dsl
|
50
52
|
attr_reader :storage_config
|
53
|
+
attr_reader :install_report
|
51
54
|
|
52
|
-
def initialize
|
55
|
+
def initialize(ui: nil)
|
53
56
|
@storage_config = Policyfile::StorageConfig.new
|
54
57
|
@dsl = Policyfile::DSL.new(storage_config)
|
55
58
|
@artifact_server_cookbook_location_specs = {}
|
59
|
+
|
60
|
+
@ui = ui || UI.null
|
61
|
+
@install_report = Policyfile::Reports::Install.new(ui: @ui, policyfile_compiler: self)
|
56
62
|
end
|
57
63
|
|
58
64
|
def error!
|
@@ -86,6 +92,7 @@ module ChefDK
|
|
86
92
|
spec = cookbook_location_spec_for(cookbook_name)
|
87
93
|
if spec.nil? or !spec.version_fixed?
|
88
94
|
spec = create_spec_for_cookbook(cookbook_name, version)
|
95
|
+
install_report.installing_cookbook(spec)
|
89
96
|
spec.ensure_cached
|
90
97
|
end
|
91
98
|
end
|
@@ -213,6 +220,12 @@ module ChefDK
|
|
213
220
|
self
|
214
221
|
end
|
215
222
|
|
223
|
+
def fixed_version_cookbooks_specs
|
224
|
+
@fixed_version_cookbooks_specs ||= cookbook_location_specs.select do |_cookbook_name, cookbook_location_spec|
|
225
|
+
cookbook_location_spec.version_fixed?
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
216
229
|
private
|
217
230
|
|
218
231
|
def normalize_recipe(run_list_item)
|
@@ -228,8 +241,9 @@ module ChefDK
|
|
228
241
|
def cache_fixed_version_cookbooks
|
229
242
|
ensure_cache_dir_exists
|
230
243
|
|
231
|
-
|
232
|
-
|
244
|
+
fixed_version_cookbooks_specs.each do |name, cookbook_location_spec|
|
245
|
+
install_report.installing_fixed_version_cookbook(cookbook_location_spec)
|
246
|
+
cookbook_location_spec.ensure_cached
|
233
247
|
end
|
234
248
|
end
|
235
249
|
|
@@ -18,10 +18,51 @@
|
|
18
18
|
require 'chef-dk/policyfile/storage_config'
|
19
19
|
require 'chef-dk/policyfile/cookbook_locks'
|
20
20
|
require 'chef-dk/policyfile/solution_dependencies'
|
21
|
+
require 'chef-dk/ui'
|
21
22
|
|
22
23
|
module ChefDK
|
24
|
+
|
23
25
|
class PolicyfileLock
|
24
26
|
|
27
|
+
class InstallReport
|
28
|
+
|
29
|
+
attr_reader :ui
|
30
|
+
attr_reader :policyfile_lock
|
31
|
+
|
32
|
+
def initialize(ui: ui, policyfile_lock: nil)
|
33
|
+
@ui = ui
|
34
|
+
@policyfile_lock = policyfile_lock
|
35
|
+
|
36
|
+
@cookbook_name_width = nil
|
37
|
+
@cookbook_version_width = nil
|
38
|
+
end
|
39
|
+
|
40
|
+
def installing_fixed_version_cookbook(cookbook_spec)
|
41
|
+
verb = cookbook_spec.installed? ? "Using " : "Installing"
|
42
|
+
ui.msg("#{verb} #{format_fixed_version_cookbook(cookbook_spec)}")
|
43
|
+
end
|
44
|
+
|
45
|
+
def installing_cookbook(cookbook_lock)
|
46
|
+
verb = cookbook_lock.installed? ? "Using " : "Installing"
|
47
|
+
ui.msg("#{verb} #{format_cookbook(cookbook_lock)}")
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def format_cookbook(cookbook_lock)
|
53
|
+
"#{cookbook_lock.name.ljust(cookbook_name_width)} #{cookbook_lock.version.to_s.ljust(cookbook_version_width)}"
|
54
|
+
end
|
55
|
+
|
56
|
+
def cookbook_name_width
|
57
|
+
policyfile_lock.cookbook_locks.map { |name, _| name.size }.max
|
58
|
+
end
|
59
|
+
|
60
|
+
def cookbook_version_width
|
61
|
+
policyfile_lock.cookbook_locks.map { |_, lock| lock.version.size }.max
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
RUN_LIST_ITEM_FORMAT = /\Arecipe\[[^\s]+::[^\s]+\]\Z/.freeze
|
25
66
|
|
26
67
|
def self.build(storage_config)
|
27
68
|
lock = new(storage_config)
|
@@ -46,14 +87,18 @@ module ChefDK
|
|
46
87
|
|
47
88
|
attr_reader :cookbook_locks
|
48
89
|
|
49
|
-
|
90
|
+
attr_reader :install_report
|
91
|
+
|
92
|
+
def initialize(storage_config, ui: nil)
|
50
93
|
@name = nil
|
51
94
|
@run_list = []
|
52
95
|
@cookbook_locks = {}
|
53
96
|
@relative_paths_root = Dir.pwd
|
54
97
|
@storage_config = storage_config
|
98
|
+
@ui = ui || UI.null
|
55
99
|
|
56
100
|
@solution_dependencies = Policyfile::SolutionDependencies.new
|
101
|
+
@install_report = InstallReport.new(ui: @ui, policyfile_lock: self)
|
57
102
|
end
|
58
103
|
|
59
104
|
def lock_data_for(cookbook_name)
|
@@ -146,14 +191,10 @@ module ChefDK
|
|
146
191
|
end
|
147
192
|
|
148
193
|
def build_from_lock_data(lock_data)
|
149
|
-
|
150
|
-
|
151
|
-
lock_data
|
152
|
-
|
153
|
-
end
|
154
|
-
|
155
|
-
s = Policyfile::SolutionDependencies.from_lock(lock_data["solution_dependencies"])
|
156
|
-
@solution_dependencies = s
|
194
|
+
set_name_from_lock_data(lock_data)
|
195
|
+
set_run_list_from_lock_data(lock_data)
|
196
|
+
set_cookbook_locks_from_lock_data(lock_data)
|
197
|
+
set_solution_dependencies_from_lock_data(lock_data)
|
157
198
|
self
|
158
199
|
end
|
159
200
|
|
@@ -162,6 +203,7 @@ module ChefDK
|
|
162
203
|
ensure_cache_dir_exists
|
163
204
|
|
164
205
|
cookbook_locks.each do |cookbook_name, cookbook_lock|
|
206
|
+
install_report.installing_cookbook(cookbook_lock)
|
165
207
|
cookbook_lock.install_locked
|
166
208
|
end
|
167
209
|
end
|
@@ -175,7 +217,78 @@ module ChefDK
|
|
175
217
|
|
176
218
|
private
|
177
219
|
|
220
|
+
def set_name_from_lock_data(lock_data)
|
221
|
+
name_attribute = lock_data["name"]
|
222
|
+
|
223
|
+
raise InvalidLockfile, "lockfile does not have a `name' attribute" if name_attribute.nil?
|
224
|
+
|
225
|
+
unless name_attribute.kind_of?(String)
|
226
|
+
raise InvalidLockfile, "lockfile's name attribute must be a String (got: #{name_attribute.inspect})"
|
227
|
+
end
|
228
|
+
|
229
|
+
if name_attribute.empty?
|
230
|
+
raise InvalidLockfile, "lockfile's name attribute cannot be an empty string"
|
231
|
+
end
|
232
|
+
|
233
|
+
@name = name_attribute
|
234
|
+
|
235
|
+
end
|
236
|
+
|
237
|
+
def set_run_list_from_lock_data(lock_data)
|
238
|
+
run_list_attribute = lock_data["run_list"]
|
239
|
+
|
240
|
+
raise InvalidLockfile, "lockfile does not have a run_list attribute" if run_list_attribute.nil?
|
241
|
+
|
242
|
+
unless run_list_attribute.kind_of?(Array)
|
243
|
+
raise InvalidLockfile, "lockfile's run_list must be an array of run list items (got: #{run_list_attribute.inspect})"
|
244
|
+
end
|
245
|
+
|
246
|
+
bad_run_list_items = run_list_attribute.select { |e| e !~ RUN_LIST_ITEM_FORMAT }
|
247
|
+
|
248
|
+
unless bad_run_list_items.empty?
|
249
|
+
msg = "lockfile's run_list items must be formatted like `recipe[$COOKBOOK_NAME::$RECIPE_NAME]'. Invalid items: `#{bad_run_list_items.join("' `")}'"
|
250
|
+
raise InvalidLockfile, msg
|
251
|
+
end
|
252
|
+
|
253
|
+
@run_list = run_list_attribute
|
254
|
+
end
|
255
|
+
|
256
|
+
def set_cookbook_locks_from_lock_data(lock_data)
|
257
|
+
cookbook_lock_data = lock_data["cookbook_locks"]
|
258
|
+
|
259
|
+
if cookbook_lock_data.nil?
|
260
|
+
raise InvalidLockfile, "lockfile does not have a cookbook_locks attribute"
|
261
|
+
end
|
262
|
+
|
263
|
+
unless cookbook_lock_data.kind_of?(Hash)
|
264
|
+
raise InvalidLockfile, "lockfile's cookbook_locks attribute must be a Hash (JSON object). (got: #{cookbook_lock_data.inspect})"
|
265
|
+
end
|
266
|
+
|
267
|
+
lock_data["cookbook_locks"].each do |name, lock_info|
|
268
|
+
build_cookbook_lock_from_lock_data(name, lock_info)
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
def set_solution_dependencies_from_lock_data(lock_data)
|
273
|
+
soln_deps = lock_data["solution_dependencies"]
|
274
|
+
|
275
|
+
if soln_deps.nil?
|
276
|
+
raise InvalidLockfile, "lockfile does not have a solution_dependencies attribute"
|
277
|
+
end
|
278
|
+
|
279
|
+
unless soln_deps.kind_of?(Hash)
|
280
|
+
raise InvalidLockfile, "lockfile's solution_dependencies attribute must be a Hash (JSON object). (got: #{soln_deps.inspect})"
|
281
|
+
end
|
282
|
+
|
283
|
+
s = Policyfile::SolutionDependencies.from_lock(lock_data["solution_dependencies"])
|
284
|
+
@solution_dependencies = s
|
285
|
+
end
|
286
|
+
|
178
287
|
def build_cookbook_lock_from_lock_data(name, lock_info)
|
288
|
+
unless lock_info.kind_of?(Hash)
|
289
|
+
raise InvalidLockfile, "lockfile cookbook_locks entries must be a Hash (JSON object). (got: #{lock_info.inspect})"
|
290
|
+
end
|
291
|
+
|
179
292
|
if lock_info["cache_key"].nil?
|
180
293
|
local_cookbook(name).build_from_lock_data(lock_info)
|
181
294
|
else
|
@@ -0,0 +1,131 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) 2014 Chef Software Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
require 'chef-dk/exceptions'
|
19
|
+
require 'chef-dk/policyfile_compiler'
|
20
|
+
require 'chef-dk/policyfile/storage_config'
|
21
|
+
require 'chef-dk/policyfile_lock'
|
22
|
+
|
23
|
+
module ChefDK
|
24
|
+
module PolicyfileServices
|
25
|
+
|
26
|
+
class Install
|
27
|
+
|
28
|
+
attr_reader :root_dir
|
29
|
+
attr_reader :ui
|
30
|
+
|
31
|
+
def initialize(policyfile: nil, ui: nil, root_dir: nil)
|
32
|
+
@policyfile_relative_path = policyfile
|
33
|
+
@ui = ui
|
34
|
+
@root_dir = root_dir
|
35
|
+
|
36
|
+
@policyfile_content = nil
|
37
|
+
@policyfile_compiler = nil
|
38
|
+
end
|
39
|
+
|
40
|
+
def run
|
41
|
+
unless File.exist?(policyfile_path)
|
42
|
+
# TODO: suggest next step. Add a generator/init command? Specify path to Policyfile.rb?
|
43
|
+
# See card CC-232
|
44
|
+
raise PolicyfileNotFound, "Policyfile not found at path #{policyfile_path}"
|
45
|
+
end
|
46
|
+
|
47
|
+
if File.exist?(lockfile_path)
|
48
|
+
install_from_lock
|
49
|
+
else
|
50
|
+
generate_lock_and_install
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def policyfile_relative_path
|
55
|
+
@policyfile_relative_path || "Policyfile.rb"
|
56
|
+
end
|
57
|
+
|
58
|
+
def policyfile_path
|
59
|
+
File.expand_path(policyfile_relative_path, root_dir)
|
60
|
+
end
|
61
|
+
|
62
|
+
def lockfile_relative_path
|
63
|
+
policyfile_relative_path.gsub(/\.rb\Z/, '') + ".lock.json"
|
64
|
+
end
|
65
|
+
|
66
|
+
def lockfile_path
|
67
|
+
File.expand_path(lockfile_relative_path, root_dir)
|
68
|
+
end
|
69
|
+
|
70
|
+
def policyfile_content
|
71
|
+
@policyfile_content ||= IO.read(policyfile_path)
|
72
|
+
end
|
73
|
+
|
74
|
+
def policyfile_compiler
|
75
|
+
@policyfile_compiler ||= ChefDK::PolicyfileCompiler.evaluate(policyfile_content, policyfile_path, ui: ui)
|
76
|
+
end
|
77
|
+
|
78
|
+
def expanded_run_list
|
79
|
+
policyfile_compiler.expanded_run_list.to_s
|
80
|
+
end
|
81
|
+
|
82
|
+
def policyfile_lock_content
|
83
|
+
@policyfile_lock_content ||= IO.read(lockfile_path) if File.exist?(lockfile_path)
|
84
|
+
end
|
85
|
+
|
86
|
+
def policyfile_lock
|
87
|
+
return nil if policyfile_lock_content.nil?
|
88
|
+
@policyfile_lock ||= begin
|
89
|
+
lock_data = FFI_Yajl::Parser.new.parse(policyfile_lock_content)
|
90
|
+
PolicyfileLock.new(storage_config, ui: ui).build_from_lock_data(lock_data)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def storage_config
|
95
|
+
@storage_config ||= Policyfile::StorageConfig.new(relative_paths_root: root_dir)
|
96
|
+
end
|
97
|
+
|
98
|
+
def generate_lock_and_install
|
99
|
+
policyfile_compiler.error!
|
100
|
+
|
101
|
+
ui.msg "Building policy #{policyfile_compiler.name}"
|
102
|
+
ui.msg "Expanded run list: " + expanded_run_list + "\n"
|
103
|
+
|
104
|
+
ui.msg "Caching Cookbooks..."
|
105
|
+
|
106
|
+
policyfile_compiler.install
|
107
|
+
|
108
|
+
lock_data = policyfile_compiler.lock.to_lock
|
109
|
+
|
110
|
+
File.open(lockfile_path, "w+") do |f|
|
111
|
+
f.print(FFI_Yajl::Encoder.encode(lock_data, pretty: true ))
|
112
|
+
end
|
113
|
+
|
114
|
+
ui.msg ""
|
115
|
+
|
116
|
+
ui.msg "Lockfile written to #{lockfile_path}"
|
117
|
+
rescue => error
|
118
|
+
raise PolicyfileInstallError.new("Failed to generate Policyfile.lock", error)
|
119
|
+
end
|
120
|
+
|
121
|
+
def install_from_lock
|
122
|
+
ui.msg "Installing cookbooks from lock"
|
123
|
+
|
124
|
+
policyfile_lock.install_cookbooks
|
125
|
+
rescue => error
|
126
|
+
raise PolicyfileInstallError.new("Failed to install cookbooks from lockfile", error)
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|