Class: ChefApply::Action::ConvergeTarget
- Inherits:
-
Base
- Object
- Base
- ChefApply::Action::ConvergeTarget
show all
- Defined in:
- lib/chef_apply/action/converge_target.rb,
lib/chef_apply/action/converge_target/ccr_failure_mapper.rb
Defined Under Namespace
Classes: CCRFailureMapper, ConfigUploadFailed, HandlerUploadFailed, PolicyUploadFailed
Instance Attribute Summary
Attributes inherited from Base
#config, #target_host
Instance Method Summary
collapse
Methods inherited from Base
#initialize, #name, #notify, #run
Instance Method Details
#chef_report_path ⇒ Object
157
158
159
|
# File 'lib/chef_apply/action/converge_target.rb', line 157
def chef_report_path
@chef_report_path ||= target_host.normalize_path(File.join(target_host.ws_cache_path, "cache", "run-report.json"))
end
|
#create_remote_config(dir) ⇒ Object
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
# File 'lib/chef_apply/action/converge_target.rb', line 71
def create_remote_config(dir)
remote_config_path = File.join(dir, "workstation.rb")
workstation_rb = <<~EOM
local_mode true
color false
cache_path "#{target_host.ws_cache_path}"
chef_repo_path "#{target_host.ws_cache_path}"
require_relative "reporter"
reporter = ChefApply::Reporter.new
report_handlers << reporter
exception_handlers << reporter
EOM
unless ChefApply::Config.chef.chef_license.nil?
workstation_rb << <<~EOM
chef_license "#{ChefApply::Config.chef.chef_license}"
EOM
end
log_settings = ChefApply::Config.log
unless log_settings.target_level.nil?
workstation_rb << <<~EOM
log_level :#{log_settings.target_level}
EOM
end
dc = ChefApply::Config.data_collector
if !dc.url.nil? && !dc.token.nil?
workstation_rb << <<~EOM
data_collector.server_url "#{dc.url}"
data_collector.token "#{dc.token}"
data_collector.mode :solo
data_collector.organization "Chef Workstation"
EOM
end
begin
config_file = Tempfile.new
config_file.write(workstation_rb)
config_file.close
target_host.upload_file(config_file.path, remote_config_path)
rescue RuntimeError
raise ConfigUploadFailed.new
ensure
config_file.unlink
end
remote_config_path
end
|
#create_remote_handler(remote_dir) ⇒ Object
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
# File 'lib/chef_apply/action/converge_target.rb', line 125
def create_remote_handler(remote_dir)
remote_handler_path = File.join(remote_dir, "reporter.rb")
begin
handler_file = Tempfile.new
handler_file.write(File.read(File.join(__dir__, "reporter.rb")))
handler_file.close
target_host.upload_file(handler_file.path, remote_handler_path)
rescue RuntimeError
raise HandlerUploadFailed.new
ensure
handler_file.unlink
end
remote_handler_path
end
|
#create_remote_policy(local_policy_path, remote_dir_path) ⇒ Object
59
60
61
62
63
64
65
66
67
68
69
|
# File 'lib/chef_apply/action/converge_target.rb', line 59
def create_remote_policy(local_policy_path, remote_dir_path)
remote_policy_path = File.join(remote_dir_path, File.basename(local_policy_path))
notify(:creating_remote_policy)
begin
target_host.upload_file(local_policy_path, remote_policy_path)
rescue RuntimeError => e
ChefApply::Log.error(e)
raise PolicyUploadFailed.new
end
remote_policy_path
end
|
#handle_ccr_error ⇒ Object
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
|
# File 'lib/chef_apply/action/converge_target.rb', line 161
def handle_ccr_error
require_relative "converge_target/ccr_failure_mapper"
mapper_opts = {}
content = target_host.fetch_file_contents(chef_report_path)
if content.nil?
report = {}
mapper_opts[:failed_report_path] = chef_report_path
ChefApply::Log.error("Could not read remote report at #{chef_report_path}")
else
target_host.del_file(chef_report_path)
report = JSON.parse(content)
ChefApply::Log.error("Remote chef-client error follows:")
ChefApply::Log.error(report["exception"])
end
mapper = ConvergeTarget::CCRFailureMapper.new(report["exception"], mapper_opts)
mapper.raise_mapped_exception!
end
|
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
# File 'lib/chef_apply/action/converge_target.rb', line 27
def perform_action
local_policy_path = config.delete :local_policy_path
remote_tmp = target_host.temp_dir
remote_dir_path = target_host.normalize_path(remote_tmp)
remote_policy_path = create_remote_policy(local_policy_path, remote_dir_path)
remote_config_path = create_remote_config(remote_dir_path)
create_remote_handler(remote_dir_path)
upload_trusted_certs(remote_dir_path)
notify(:running_chef)
cmd_str = run_chef_cmd(remote_dir_path,
File.basename(remote_config_path),
File.basename(remote_policy_path))
c = target_host.run_command(cmd_str)
target_host.del_dir(remote_dir_path)
if c.exit_status == 0
ChefApply::Log.info(c.stdout)
notify(:success)
elsif c.exit_status == 35
notify(:reboot)
else
notify(:converge_error)
ChefApply::Log.error("Error running command [#{cmd_str}]")
ChefApply::Log.error("stdout: #{c.stdout}")
ChefApply::Log.error("stderr: #{c.stderr}")
handle_ccr_error
end
end
|
#run_chef_cmd(working_dir, config_file, policy) ⇒ Object
Chef will try ‘downloading’ the policy from the internet unless we pass it a valid, local file in the working directory. By pointing it at a local file it will just copy it instead of trying to download it.
Chef 13 on Linux requires full path specifiers for –config and –recipe-url while on Chef 13 and 14 on Windows must use relative specifiers to prevent URI from causing an error (github.com/chef/chef/pull/7223/files).
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
|
# File 'lib/chef_apply/action/converge_target.rb', line 189
def run_chef_cmd(working_dir, config_file, policy)
case target_host.base_os
when :windows
"Set-Location -Path #{working_dir}; " +
"chef-client -z --config #{File.join(working_dir, config_file)} --recipe-url #{File.join(working_dir, policy)} | Out-Null; " +
"Set-Location C:/; " +
"exit $LASTEXITCODE"
else
"bash -c 'cd #{working_dir}; /opt/chef/bin/chef-client -z --config #{File.join(working_dir, config_file)} --recipe-url #{File.join(working_dir, policy)}'"
end
end
|
#upload_trusted_certs(dir) ⇒ Object
143
144
145
146
147
148
149
150
151
152
153
154
155
|
# File 'lib/chef_apply/action/converge_target.rb', line 143
def upload_trusted_certs(dir)
local_tcd = Chef::Util::PathHelper.escape_glob_dir(ChefApply::Config.chef.trusted_certs_dir)
certs = Dir.glob(File.join(local_tcd, "*.{crt,pem}"))
return if certs.empty?
notify(:uploading_trusted_certs)
remote_tcd = "#{dir}/trusted_certs"
target_host.make_directory(remote_tcd)
certs.each do |cert_file|
target_host.upload_file(cert_file, "#{remote_tcd}/#{File.basename(cert_file)}")
end
end
|