aws-codedeploy-agent 0.0.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.
- data/.gitignore +2 -0
- data/CHANGES.md +3 -0
- data/Gemfile +13 -0
- data/LICENSE +177 -0
- data/NOTICE +2 -0
- data/README.md +16 -0
- data/aws-codedeploy-agent.gemspec +39 -0
- data/bin/codedeploy-agent +78 -0
- data/bin/codedeploy-install +15 -0
- data/bin/codedeploy-uninstall +13 -0
- data/certs/host-agent-deployment-signer-ca-chain.pem +76 -0
- data/conf/codedeployagent.yml +9 -0
- data/init.d/codedeploy-agent +61 -0
- data/lib/core_ext.rb +71 -0
- data/lib/instance_agent.rb +35 -0
- data/lib/instance_agent/agent/base.rb +34 -0
- data/lib/instance_agent/codedeploy_plugin/application_specification/ace_info.rb +133 -0
- data/lib/instance_agent/codedeploy_plugin/application_specification/acl_info.rb +163 -0
- data/lib/instance_agent/codedeploy_plugin/application_specification/application_specification.rb +142 -0
- data/lib/instance_agent/codedeploy_plugin/application_specification/context_info.rb +23 -0
- data/lib/instance_agent/codedeploy_plugin/application_specification/file_info.rb +23 -0
- data/lib/instance_agent/codedeploy_plugin/application_specification/linux_permission_info.rb +121 -0
- data/lib/instance_agent/codedeploy_plugin/application_specification/mode_info.rb +66 -0
- data/lib/instance_agent/codedeploy_plugin/application_specification/range_info.rb +134 -0
- data/lib/instance_agent/codedeploy_plugin/application_specification/script_info.rb +27 -0
- data/lib/instance_agent/codedeploy_plugin/codedeploy_control.rb +72 -0
- data/lib/instance_agent/codedeploy_plugin/command_executor.rb +357 -0
- data/lib/instance_agent/codedeploy_plugin/command_poller.rb +146 -0
- data/lib/instance_agent/codedeploy_plugin/deployment_specification.rb +150 -0
- data/lib/instance_agent/codedeploy_plugin/hook_executor.rb +206 -0
- data/lib/instance_agent/codedeploy_plugin/install_instruction.rb +374 -0
- data/lib/instance_agent/codedeploy_plugin/installer.rb +143 -0
- data/lib/instance_agent/codedeploy_plugin/request_helper.rb +28 -0
- data/lib/instance_agent/config.rb +43 -0
- data/lib/instance_agent/log.rb +3 -0
- data/lib/instance_agent/platform.rb +17 -0
- data/lib/instance_agent/platform/linux_util.rb +57 -0
- data/lib/instance_agent/runner/child.rb +57 -0
- data/lib/instance_agent/runner/master.rb +103 -0
- data/lib/instance_metadata.rb +47 -0
- data/test/certificate_helper.rb +120 -0
- data/test/helpers/instance_agent_helper.rb +25 -0
- data/test/instance_agent/agent/base_test.rb +49 -0
- data/test/instance_agent/codedeploy_plugin/application_specification_test.rb +1710 -0
- data/test/instance_agent/codedeploy_plugin/codedeploy_control_test.rb +51 -0
- data/test/instance_agent/codedeploy_plugin/command_executor_test.rb +513 -0
- data/test/instance_agent/codedeploy_plugin/command_poller_test.rb +459 -0
- data/test/instance_agent/codedeploy_plugin/deployment_specification_test.rb +335 -0
- data/test/instance_agent/codedeploy_plugin/hook_executor_test.rb +250 -0
- data/test/instance_agent/codedeploy_plugin/install_instruction_test.rb +566 -0
- data/test/instance_agent/codedeploy_plugin/installer_test.rb +519 -0
- data/test/instance_agent/codedeploy_plugin/request_helper_test.rb +37 -0
- data/test/instance_agent/config_test.rb +64 -0
- data/test/instance_agent/runner/child_test.rb +87 -0
- data/test/instance_metadata_test.rb +97 -0
- data/test/test_helper.rb +16 -0
- data/vendor/gems/.codedeploy-commands-1.0.0.created.rid +1 -0
- data/vendor/gems/codedeploy-commands/apis/CodeDeployCommand.api.json +372 -0
- data/vendor/gems/codedeploy-commands/codedeploy-commands-1.0.0.gemspec +28 -0
- data/vendor/gems/codedeploy-commands/lib/aws/codedeploy_commands.rb +18 -0
- data/vendor/gems/codedeploy-commands/lib/aws/plugins/certificate_authority.rb +12 -0
- data/vendor/gems/codedeploy-commands/lib/aws/plugins/deploy_control_endpoint.rb +22 -0
- data/vendor/gems/process_manager/README.md +1 -0
- data/vendor/gems/process_manager/lib/blank.rb +153 -0
- data/vendor/gems/process_manager/lib/core_ext.rb +73 -0
- data/vendor/gems/process_manager/lib/process_manager.rb +49 -0
- data/vendor/gems/process_manager/lib/process_manager/child.rb +119 -0
- data/vendor/gems/process_manager/lib/process_manager/config.rb +112 -0
- data/vendor/gems/process_manager/lib/process_manager/log.rb +107 -0
- data/vendor/gems/process_manager/lib/process_manager/master.rb +322 -0
- data/vendor/gems/process_manager/process_manager-0.0.13.gemspec +42 -0
- data/vendor/specifications/aws-sdk-core-2.0.5.gemspec +39 -0
- data/vendor/specifications/builder-3.2.2.gemspec +29 -0
- data/vendor/specifications/codedeploy-commands-1.0.0.gemspec +28 -0
- data/vendor/specifications/gli-2.5.6.gemspec +51 -0
- data/vendor/specifications/jamespath-0.5.1.gemspec +35 -0
- data/vendor/specifications/little-plugger-1.1.3.gemspec +32 -0
- data/vendor/specifications/logging-1.8.1.gemspec +44 -0
- data/vendor/specifications/multi_json-1.7.7.gemspec +30 -0
- data/vendor/specifications/multi_json-1.8.4.gemspec +30 -0
- data/vendor/specifications/multi_xml-0.5.5.gemspec +30 -0
- data/vendor/specifications/process_manager-0.0.13.gemspec +42 -0
- data/vendor/specifications/simple_pid-0.2.1.gemspec +28 -0
- metadata +377 -0
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
require 'ostruct'
|
|
3
|
+
require 'certificate_helper'
|
|
4
|
+
|
|
5
|
+
class DeploymentSpecificationTest < InstanceAgentTestCase
|
|
6
|
+
context 'The Deployment Specification' do
|
|
7
|
+
def generate_signed_message_for(map)
|
|
8
|
+
message = @cert_helper.sign_message(map.to_json)
|
|
9
|
+
spec = OpenStruct.new({ :payload => message })
|
|
10
|
+
spec.format = "PKCS7/JSON"
|
|
11
|
+
|
|
12
|
+
return spec
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
setup do
|
|
16
|
+
@cert_helper = CertificateHelper.new
|
|
17
|
+
@deployment_id = SecureRandom.uuid.to_s
|
|
18
|
+
@deployment_group_id = SecureRandom.uuid.to_s
|
|
19
|
+
@s3Revision = {
|
|
20
|
+
"Bucket" => "mybucket",
|
|
21
|
+
"Key" => "mykey",
|
|
22
|
+
"BundleType" => "tar"
|
|
23
|
+
}
|
|
24
|
+
@revision = {
|
|
25
|
+
"RevisionType" => "S3",
|
|
26
|
+
"S3Revision" => @s3Revision
|
|
27
|
+
}
|
|
28
|
+
@deployment_spec = {
|
|
29
|
+
"DeploymentId" => @deployment_id,
|
|
30
|
+
"DeploymentGroupId" => @deployment_group_id,
|
|
31
|
+
"Revision" => @revision
|
|
32
|
+
}
|
|
33
|
+
@packed_message = generate_signed_message_for(@deployment_spec)
|
|
34
|
+
InstanceAgent::Config.init
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
context "with JSON format" do
|
|
38
|
+
should "populate the deployment id" do
|
|
39
|
+
parsed_deployment_spec = InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
|
|
40
|
+
assert_equal @deployment_id, parsed_deployment_spec.deployment_id
|
|
41
|
+
assert_equal @s3Revision, parsed_deployment_spec.revision
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
context "with arn deployment id" do
|
|
46
|
+
setup do
|
|
47
|
+
@deployment_spec = {
|
|
48
|
+
"DeploymentId" => "arn:aws:codedeploy:region:account:deployment/#{@deployment_id}",
|
|
49
|
+
"DeploymentGroupId" => @deployment_group_id,
|
|
50
|
+
"Revision" => @revision
|
|
51
|
+
}
|
|
52
|
+
@packed_message = generate_signed_message_for(@deployment_spec)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
should "populate the Bundle" do
|
|
56
|
+
parsed_deployment_spec = InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
|
|
57
|
+
assert_equal @deployment_id, parsed_deployment_spec.deployment_id
|
|
58
|
+
assert_equal @deployment_group_id, parsed_deployment_spec.deployment_group_id
|
|
59
|
+
assert_equal @s3Revision, parsed_deployment_spec.revision
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
context "with an unsupported format" do
|
|
64
|
+
setup do
|
|
65
|
+
@packed_message.format = "XML"
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
should "raise an exception" do
|
|
69
|
+
assert_raised_with_message("Unsupported DeploymentSpecification format: XML") do
|
|
70
|
+
parsed_deployment_spec = InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
context "with additional data" do
|
|
76
|
+
setup do
|
|
77
|
+
@deployment_spec["AdditionalData"] = "test"
|
|
78
|
+
@packed_message = generate_signed_message_for(@deployment_spec)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
should "populate the Bundle" do
|
|
82
|
+
parsed_deployment_spec = InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
|
|
83
|
+
assert_equal @deployment_id, parsed_deployment_spec.deployment_id
|
|
84
|
+
assert_equal @deployment_group_id, parsed_deployment_spec.deployment_group_id
|
|
85
|
+
assert_equal @s3Revision, parsed_deployment_spec.revision
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
context "with a nil format" do
|
|
90
|
+
setup do
|
|
91
|
+
@packed_message.format = nil
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
should "raise an exception" do
|
|
95
|
+
assert_raised_with_message("Unsupported DeploymentSpecification format: ") do
|
|
96
|
+
InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
context "is nil" do
|
|
102
|
+
setup do
|
|
103
|
+
@packed_message = nil
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
should "raise a runtime exception" do
|
|
107
|
+
assert_raised_with_message("Provided deployment spec was nil") do
|
|
108
|
+
InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
context "with no deployment id" do
|
|
114
|
+
setup do
|
|
115
|
+
@deployment_spec.delete("DeploymentId")
|
|
116
|
+
@packed_message = generate_signed_message_for(@deployment_spec)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
should "raise a runtime exception" do
|
|
120
|
+
assert_raised_with_message("Deployment Spec has no DeploymentId") do
|
|
121
|
+
InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
context "with null deployment id" do
|
|
127
|
+
setup do
|
|
128
|
+
@deployment_spec["DeploymentId"] = nil
|
|
129
|
+
@packed_message = generate_signed_message_for(@deployment_spec)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
should "raise a runtime exception" do
|
|
133
|
+
assert_raised_with_message("Deployment Spec has no DeploymentId") do
|
|
134
|
+
InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
context "with empty deployment id" do
|
|
140
|
+
setup do
|
|
141
|
+
@deployment_spec["DeploymentId"] = ""
|
|
142
|
+
@packed_message = generate_signed_message_for(@deployment_spec)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
should "raise a runtime exception" do
|
|
146
|
+
assert_raised_with_message("Deployment Spec has no DeploymentId") do
|
|
147
|
+
InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
context "with no instance group id" do
|
|
153
|
+
setup do
|
|
154
|
+
@deployment_spec.delete("DeploymentGroupId")
|
|
155
|
+
@packed_message = generate_signed_message_for(@deployment_spec)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
should "raise a runtime exception" do
|
|
159
|
+
assert_raised_with_message("Deployment Spec has no DeploymentGroupId") do
|
|
160
|
+
InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
context "with null instance group id" do
|
|
166
|
+
setup do
|
|
167
|
+
@deployment_spec["DeploymentGroupId"] = nil
|
|
168
|
+
@packed_message = generate_signed_message_for(@deployment_spec)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
should "raise a runtime exception" do
|
|
172
|
+
assert_raised_with_message("Deployment Spec has no DeploymentGroupId") do
|
|
173
|
+
InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
context "with empty instance group id" do
|
|
179
|
+
setup do
|
|
180
|
+
@deployment_spec["DeploymentGroupId"] = ""
|
|
181
|
+
@packed_message = generate_signed_message_for(@deployment_spec)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
should "raise a runtime exception" do
|
|
185
|
+
assert_raised_with_message("Deployment Spec has no DeploymentGroupId") do
|
|
186
|
+
InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
context "with no target revision" do
|
|
192
|
+
setup do
|
|
193
|
+
@deployment_spec.delete("Revision")
|
|
194
|
+
@packed_message = generate_signed_message_for(@deployment_spec)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
should "raise a runtime exception" do
|
|
198
|
+
assert_raised_with_message('Must specify a revison') do
|
|
199
|
+
InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
context "with null target revision" do
|
|
205
|
+
setup do
|
|
206
|
+
@deployment_spec["Revision"] = nil
|
|
207
|
+
@packed_message = generate_signed_message_for(@deployment_spec)
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
should "raise a runtime exception" do
|
|
211
|
+
assert_raised_with_message('Must specify a revison') do
|
|
212
|
+
InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
context "with empty target revision" do
|
|
218
|
+
setup do
|
|
219
|
+
@deployment_spec["Revision"] = ""
|
|
220
|
+
@packed_message = generate_signed_message_for(@deployment_spec)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
should "raise a runtime exception" do
|
|
224
|
+
assert_raised_with_message("Must specify a revision source") do
|
|
225
|
+
InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
context "with S3 Revision" do
|
|
231
|
+
should "parse correctly" do
|
|
232
|
+
parsed_deployment_spec = InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
|
|
233
|
+
assert_equal @s3Revision, parsed_deployment_spec.revision
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
should "raise when Bucket is missing" do
|
|
237
|
+
@s3Revision = {
|
|
238
|
+
"Key" => "mykey",
|
|
239
|
+
"BundleType" => "tar"
|
|
240
|
+
}
|
|
241
|
+
@revision = {
|
|
242
|
+
"RevisionType" => "S3",
|
|
243
|
+
"S3Revision" => @s3Revision
|
|
244
|
+
}
|
|
245
|
+
@deployment_spec = {
|
|
246
|
+
"DeploymentId" => @deployment_id,
|
|
247
|
+
"DeploymentGroupId" => @deployment_group_id,
|
|
248
|
+
"Revision" => @revision
|
|
249
|
+
}
|
|
250
|
+
@packed_message = generate_signed_message_for(@deployment_spec)
|
|
251
|
+
|
|
252
|
+
assert_raised_with_message("S3Revision in Deployment Spec must specify Bucket, Key and BundleType") do
|
|
253
|
+
InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
should "raise when Key is missing" do
|
|
258
|
+
@s3Revision = {
|
|
259
|
+
"Bucket" => "mybucket",
|
|
260
|
+
"BundleType" => "tar"
|
|
261
|
+
}
|
|
262
|
+
@revision = {
|
|
263
|
+
"RevisionType" => "S3",
|
|
264
|
+
"S3Revision" => @s3Revision
|
|
265
|
+
}
|
|
266
|
+
@deployment_spec = {
|
|
267
|
+
"DeploymentId" => @deployment_id,
|
|
268
|
+
"DeploymentGroupId" => @deployment_group_id,
|
|
269
|
+
"Revision" => @revision
|
|
270
|
+
}
|
|
271
|
+
@packed_message = generate_signed_message_for(@deployment_spec)
|
|
272
|
+
|
|
273
|
+
assert_raised_with_message("S3Revision in Deployment Spec must specify Bucket, Key and BundleType") do
|
|
274
|
+
InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
should "raise when BundleType is missing" do
|
|
279
|
+
@s3Revision = {
|
|
280
|
+
"Bucket" => "mybucket",
|
|
281
|
+
"Key" => "mykey"
|
|
282
|
+
}
|
|
283
|
+
@revision = {
|
|
284
|
+
"RevisionType" => "S3",
|
|
285
|
+
"S3Revision" => @s3Revision
|
|
286
|
+
}
|
|
287
|
+
@deployment_spec = {
|
|
288
|
+
"DeploymentId" => @deployment_id,
|
|
289
|
+
"DeploymentGroupId" => @deployment_group_id,
|
|
290
|
+
"Revision" => @revision
|
|
291
|
+
}
|
|
292
|
+
@packed_message = generate_signed_message_for(@deployment_spec)
|
|
293
|
+
|
|
294
|
+
assert_raised_with_message("S3Revision in Deployment Spec must specify Bucket, Key and BundleType") do
|
|
295
|
+
InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
should "raise when bundle type is not a supported format" do
|
|
300
|
+
@s3Revision = {
|
|
301
|
+
"Bucket" => "mybucket",
|
|
302
|
+
"Key" => "mykey",
|
|
303
|
+
"BundleType" => "bar"
|
|
304
|
+
}
|
|
305
|
+
@revision = {
|
|
306
|
+
"RevisionType" => "S3",
|
|
307
|
+
"S3Revision" => @s3Revision
|
|
308
|
+
}
|
|
309
|
+
@deployment_spec = {
|
|
310
|
+
"DeploymentId" => @deployment_id,
|
|
311
|
+
"DeploymentGroupId" => @deployment_group_id,
|
|
312
|
+
"Revision" => @revision
|
|
313
|
+
}
|
|
314
|
+
@packed_message = generate_signed_message_for(@deployment_spec)
|
|
315
|
+
|
|
316
|
+
assert_raised_with_message("BundleType in S3Revision must be tar, tgz or zip") do
|
|
317
|
+
InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
should "raise when JSON submitted as PKCS7/JSON" do
|
|
322
|
+
@packed_message.payload = @deployment_spec.to_json
|
|
323
|
+
|
|
324
|
+
assert_raised_with_message("Could not parse the PKCS7: nested asn1 error") do
|
|
325
|
+
begin
|
|
326
|
+
InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
|
|
327
|
+
rescue ArgumentError => e
|
|
328
|
+
raise e.message
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
end
|
|
335
|
+
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
require 'stringio'
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
require 'instance_agent/codedeploy_plugin/installer'
|
|
5
|
+
require 'com/amazon/codedeploy/command/v20141006/host_command_instance'
|
|
6
|
+
|
|
7
|
+
class HookExecutorTest < InstanceAgentTestCase
|
|
8
|
+
|
|
9
|
+
include InstanceAgent::CodeDeployPlugin
|
|
10
|
+
|
|
11
|
+
def create_full_hook_executor
|
|
12
|
+
HookExecutor.new ({:lifecycle_event => @lifecycle_event,
|
|
13
|
+
:deployment_root_dir => @deployment_root_dir,
|
|
14
|
+
:last_successful_deployment_dir => @last_successful_deployment_dir,
|
|
15
|
+
:app_spec_path => @app_spec_path})
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
context "testing hook executor" do
|
|
19
|
+
setup do
|
|
20
|
+
@deployment_root_dir = "deployment/root/dir"
|
|
21
|
+
@last_successful_deployment_dir = "last/deployment/root/dir"
|
|
22
|
+
@app_spec_path = "app_spec"
|
|
23
|
+
@app_spec = { "version" => 0.0, "os" => "linux" }
|
|
24
|
+
YAML.stubs(:load).returns(@app_spec)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
context "when creating a hook command" do
|
|
28
|
+
context "first deployment pre-download scripts" do
|
|
29
|
+
setup do
|
|
30
|
+
File.stubs(:exist?).returns(false)
|
|
31
|
+
@lifecycle_event = "ApplicationStop"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
should "do nothing" do
|
|
35
|
+
@hook_executor = HookExecutor.new ({:lifecycle_event => @lifecycle_event,
|
|
36
|
+
:deployment_root_dir => @deployment_root_dir,
|
|
37
|
+
:app_spec_path => @app_spec_path})
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
context "first deployment post-download scripts" do
|
|
42
|
+
setup do
|
|
43
|
+
File.stubs(:exist?).returns(false)
|
|
44
|
+
@lifecycle_event = "ValidateService"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
should "raise an error" do
|
|
48
|
+
assert_raise do
|
|
49
|
+
@hook_executor = HookExecutor.new ({:lifecycle_event => @lifecycle_event,
|
|
50
|
+
:deployment_root_dir => @deployment_root_dir})
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
context "all information provided" do
|
|
56
|
+
setup do
|
|
57
|
+
@lifecycle_event = "ValidateService"
|
|
58
|
+
ApplicationSpecification.stubs(:parse)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
should "parse an app spec from the current deployments directory" do
|
|
62
|
+
File.expects(:read).with(File.join(@deployment_root_dir, 'deployment-archive', @app_spec_path))
|
|
63
|
+
@hook_executor = create_full_hook_executor
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
context "hook is before download bundle" do
|
|
67
|
+
setup do
|
|
68
|
+
@lifecycle_event = "ApplicationStop"
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
should "parse an app spec from the previous deployment's directory" do
|
|
72
|
+
File.expects(:read).with(File.join(@last_successful_deployment_dir, 'deployment-archive', @app_spec_path))
|
|
73
|
+
@hook_executor = create_full_hook_executor
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
context "when executing a hook command" do
|
|
80
|
+
setup do
|
|
81
|
+
@lifecycle_event = "ValidateService"
|
|
82
|
+
File.stubs(:read).with(File.join(@deployment_root_dir, 'deployment-archive', @app_spec_path))
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
context "no scripts to run for a given hook" do
|
|
86
|
+
setup do
|
|
87
|
+
@app_spec = {"version" => 0.0, "os" => "linux", "hooks" => {}}
|
|
88
|
+
YAML.stubs(:load).returns(@app_spec)
|
|
89
|
+
@hook_executor = create_full_hook_executor
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
should "do nothing" do
|
|
93
|
+
@hook_executor.execute
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
context "running with a single basic script" do
|
|
98
|
+
setup do
|
|
99
|
+
@app_spec = {"version" => 0.0, "os" => "linux", "hooks" => {'ValidateService'=>[{'location'=>'test'}]}}
|
|
100
|
+
YAML.stubs(:load).returns(@app_spec)
|
|
101
|
+
@script_location = File.join(@deployment_root_dir, 'deployment-archive', 'test')
|
|
102
|
+
@hook_executor = create_full_hook_executor
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
context "when hook script doesn't exist" do
|
|
106
|
+
setup do
|
|
107
|
+
File.stubs(:exist?).with(@script_location).returns(false)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
should "raise and exception" do
|
|
111
|
+
assert_raised_with_message('Script does not exist at specified location: test', ScriptError)do
|
|
112
|
+
@hook_executor.execute
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
context "when the file exists" do
|
|
118
|
+
setup do
|
|
119
|
+
File.stubs(:exist?).with(@script_location).returns(true)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
context "and isn't executable" do
|
|
123
|
+
setup do
|
|
124
|
+
File.stubs(:executable?).with(@script_location).returns(false)
|
|
125
|
+
InstanceAgent::Log.expects(:send).with(:warn, 'InstanceAgent::CodeDeployPlugin::HookExecutor: Script at specified location: test is not executable. Trying to make it executable.')
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
should "log and make the hook script executable" do
|
|
129
|
+
FileUtils.expects(:chmod)#.with("+x", @script_location)
|
|
130
|
+
assert_raised_with_message('No such file or directory - deployment/root/dir/deployment-archive/test', Errno::ENOENT) do
|
|
131
|
+
@hook_executor.execute
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
context "and setting executable fails" do
|
|
136
|
+
setup do
|
|
137
|
+
FileUtils.stubs(:chmod).raises("An exception")
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
should "raise an exception" do
|
|
141
|
+
assert_raised_with_message('Unable to set script at specified location: test as executable', ScriptError) do
|
|
142
|
+
@hook_executor.execute
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
context "files are executable (both intial checks pass)" do
|
|
149
|
+
setup do
|
|
150
|
+
File.stubs(:executable?).with(@script_location).returns(true)
|
|
151
|
+
@mock_pipe = mock
|
|
152
|
+
dummy_array = mock
|
|
153
|
+
@mock_pipe.stubs(:each_line).returns(dummy_array)
|
|
154
|
+
@mock_pipe.stubs(:close)
|
|
155
|
+
dummy_array.stubs(:each).returns(nil)
|
|
156
|
+
@wait_thr = mock
|
|
157
|
+
@value = mock
|
|
158
|
+
@wait_thr.stubs(:value).returns(@value)
|
|
159
|
+
@wait_thr.stubs(:join).returns(1000)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
context "scripts timeout" do
|
|
163
|
+
setup do
|
|
164
|
+
@app_spec = { "version" => 0.0, "os" => "linux", "hooks" => {'ValidateService'=> [{"location"=>"test", "timeout"=>"30"}]}}
|
|
165
|
+
YAML.stubs(:load).returns(@app_spec)
|
|
166
|
+
@hook_executor = create_full_hook_executor
|
|
167
|
+
@wait_thr.stubs(:join).with(30).returns(nil)
|
|
168
|
+
@wait_thr.stubs(:pid)
|
|
169
|
+
mock_pipe = mock
|
|
170
|
+
Open3.stubs(:popen3).with(@script_location, :pgroup=>true).yields([@mock_pipe,@mock_pipe,@mock_pipe,@wait_thr])
|
|
171
|
+
Process.stubs(:kill)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
should "raise and exception" do
|
|
175
|
+
assert_raised_with_message('Script at specified location: test failed to complete in 30 seconds', ScriptError) do
|
|
176
|
+
@hook_executor.execute
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
context "Scripts run with a runas" do
|
|
182
|
+
setup do
|
|
183
|
+
@app_spec = { "version" => 0.0, "os" => "linux", "hooks" => {'ValidateService'=> [{"location"=>"test", "runas"=>"user"}]}}
|
|
184
|
+
YAML.stubs(:load).returns(@app_spec)
|
|
185
|
+
@hook_executor = create_full_hook_executor
|
|
186
|
+
mock_pipe = mock
|
|
187
|
+
Open3.stubs(:popen3).with('su user -c ' + @script_location, :pgroup=>true).yields([@mock_pipe,@mock_pipe,@mock_pipe,@wait_thr])
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
context "scripts fail" do
|
|
191
|
+
setup do
|
|
192
|
+
@value.stubs(:exitstatus).returns(1)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
should "raise an exception" do
|
|
196
|
+
assert_raised_with_message('Script at specified location: test run as user user failed with exit code 1', ScriptError) do
|
|
197
|
+
@hook_executor.execute
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
context "scripts pass" do
|
|
203
|
+
setup do
|
|
204
|
+
@value.stubs(:exitstatus).returns(0)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
should "execute script with runas" do
|
|
208
|
+
Open3.expects(:popen3).with('su user -c ' + @script_location, :pgroup=>true).yields([@mock_pipe,@mock_pipe,@mock_pipe,@wait_thr])
|
|
209
|
+
@hook_executor.execute
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
context "Scripts run without a runas" do
|
|
215
|
+
setup do
|
|
216
|
+
@app_spec = { "version" => 0.0, "os" => "linux", "hooks" => {'ValidateService'=> [{"location"=>"test"}]}}
|
|
217
|
+
YAML.stubs(:load).returns(@app_spec)
|
|
218
|
+
@hook_executor = create_full_hook_executor
|
|
219
|
+
Open3.stubs(:popen3).with(@script_location, :pgroup=>true).yields([@mock_pipe,@mock_pipe,@mock_pipe,@wait_thr])
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
context "Scripts fail" do
|
|
223
|
+
setup do
|
|
224
|
+
@value.stubs(:exitstatus).returns(1)
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
should "raise an exception" do
|
|
228
|
+
assert_raised_with_message('Script at specified location: test failed with exit code 1', ScriptError) do
|
|
229
|
+
@hook_executor.execute
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
context "Scripts pass" do
|
|
235
|
+
setup do
|
|
236
|
+
@value.stubs(:exitstatus).returns(0)
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
should "execute script" do
|
|
240
|
+
Open3.expects(:popen3).with(@script_location, :pgroup=>true).yields([@mock_pipe,@mock_pipe,@mock_pipe,@wait_thr])
|
|
241
|
+
@hook_executor.execute
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
end
|