Skip to content

Commit 6a3e34a

Browse files
jcbhlmwjones-aws
authored andcommitted
Expose s3 environment variables to hook execution
This patch exposes the bucket name, key, version, and etag of the bundle if we are running an s3 deployment.
1 parent 6ce81f9 commit 6a3e34a

File tree

4 files changed

+68
-18
lines changed

4 files changed

+68
-18
lines changed

lib/instance_agent/plugins/codedeploy/command_executor.rb

+24-1
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,30 @@ def create_hook_executor(lifecycle_event, deployment_spec)
222222
:deployment_root_dir => deployment_root_dir(deployment_spec),
223223
:last_successful_deployment_dir => last_successful_deployment_dir(deployment_spec.deployment_group_id),
224224
:most_recent_deployment_dir => most_recent_deployment_dir(deployment_spec.deployment_group_id),
225-
:app_spec_path => deployment_spec.app_spec_path)
225+
:app_spec_path => deployment_spec.app_spec_path,
226+
:revision_envs => get_revision_envs(deployment_spec))
227+
end
228+
229+
private
230+
def get_revision_envs(deployment_spec)
231+
case deployment_spec.revision_source
232+
when 'S3'
233+
return get_s3_envs(deployment_spec)
234+
when 'GitHub', 'Local File', 'Local Directory'
235+
return {}
236+
else
237+
raise "Unknown revision type '#{deployment_spec.revision_source}'"
238+
end
239+
end
240+
241+
private
242+
def get_s3_envs(deployment_spec)
243+
return {
244+
"BUNDLE_BUCKET" => deployment_spec.bucket,
245+
"BUNDLE_KEY" => deployment_spec.key,
246+
"BUNDLE_VERSION" => deployment_spec.version,
247+
"BUNDLE_ETAG" => deployment_spec.etag
248+
}
226249
end
227250

228251
private

lib/instance_agent/plugins/codedeploy/hook_executor.rb

+1
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ def initialize(arguments = {})
106106
'APPLICATION_NAME' => @application_name,
107107
'DEPLOYMENT_GROUP_NAME' => @deployment_group_name,
108108
'DEPLOYMENT_GROUP_ID' => @deployment_group_id}
109+
@child_envs.merge!(arguments[:revision_envs]) if arguments[:revision_envs]
109110
end
110111

111112
def is_noop?

test/instance_agent/plugins/codedeploy/command_executor_test.rb

+13-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,15 @@ def generate_signed_message_for(map)
1616
return spec
1717
end
1818

19+
def s3_env_vars()
20+
return {
21+
"BUNDLE_BUCKET" => @s3Revision["Bucket"],
22+
"BUNDLE_KEY" => @s3Revision["Key"],
23+
"BUNDLE_VERSION" => @s3Revision["Version"],
24+
"BUNDLE_ETAG" => @s3Revision["Etag"]
25+
}
26+
end
27+
1928
context 'The CodeDeploy Plugin Command Executor' do
2029
setup do
2130
@test_hook_mapping = { "BeforeBlockTraffic"=>["BeforeBlockTraffic"],
@@ -711,7 +720,8 @@ def generate_signed_message_for(map)
711720
:deployment_root_dir => @deployment_root_dir,
712721
:last_successful_deployment_dir => nil,
713722
:most_recent_deployment_dir => nil,
714-
:app_spec_path => 'appspec.yml'}
723+
:app_spec_path => 'appspec.yml',
724+
:revision_envs => s3_env_vars()}
715725
@mock_hook_executor = mock
716726
end
717727

@@ -906,7 +916,8 @@ def generate_signed_message_for(map)
906916
:deployment_type => @deployment_type,
907917
:last_successful_deployment_dir => nil,
908918
:most_recent_deployment_dir => nil,
909-
:app_spec_path => 'appspec.yml'}
919+
:app_spec_path => 'appspec.yml',
920+
:revision_envs => s3_env_vars()}
910921
@hook_executor_constructor_hash_1 = hook_executor_constructor_hash.merge({:lifecycle_event => "lifecycle_event_1"})
911922
@hook_executor_constructor_hash_2 = hook_executor_constructor_hash.merge({:lifecycle_event => "lifecycle_event_2"})
912923
@mock_hook_executor = mock

test/instance_agent/plugins/codedeploy/hook_executor_test.rb

+30-15
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class HookExecutorTest < InstanceAgentTestCase
66

77
include InstanceAgent::Plugins::CodeDeployPlugin
88

9-
def create_full_hook_executor
9+
def create_hook_executor(map = {})
1010
HookExecutor.new ({:lifecycle_event => @lifecycle_event,
1111
:application_name => @application_name,
1212
:deployment_id => @deployment_id,
@@ -17,7 +17,8 @@ def create_full_hook_executor
1717
:deployment_root_dir => @deployment_root_dir,
1818
:last_successful_deployment_dir => @last_successful_deployment_dir,
1919
:most_recent_deployment_dir => @most_recent_deployment_dir,
20-
:app_spec_path => @app_spec_path})
20+
:app_spec_path => @app_spec_path}
21+
.merge(map))
2122
end
2223

2324
context "testing hook executor" do
@@ -91,13 +92,13 @@ def create_full_hook_executor
9192
should "fail if app spec not found" do
9293
File.stubs(:exists?).with(){|value| value.is_a?(String) && value.end_with?("/app_spec")}.returns(false)
9394
assert_raised_with_message("The CodeDeploy agent did not find an AppSpec file within the unpacked revision directory at revision-relative path \"app_spec\". The revision was unpacked to directory \"deployment/root/dir/deployment-archive\", and the AppSpec file was expected but not found at path \"deployment/root/dir/deployment-archive/app_spec\". Consult the AWS CodeDeploy Appspec documentation for more information at http://docs.aws.amazon.com/codedeploy/latest/userguide/reference-appspec-file.html", RuntimeError)do
94-
@hook_executor = create_full_hook_executor
95+
@hook_executor = create_hook_executor
9596
end
9697
end
9798

9899
should "parse an app spec from the current deployments directory" do
99100
File.expects(:read).with(File.join(@deployment_root_dir, 'deployment-archive', @app_spec_path))
100-
@hook_executor = create_full_hook_executor
101+
@hook_executor = create_hook_executor
101102
end
102103

103104
context "hook is before download bundle" do
@@ -107,7 +108,7 @@ def create_full_hook_executor
107108

108109
should "parse an app spec from the last successful deployment's directory" do
109110
File.expects(:read).with(File.join(@last_successful_deployment_dir, 'deployment-archive', @app_spec_path))
110-
@hook_executor = create_full_hook_executor
111+
@hook_executor = create_hook_executor
111112
end
112113
end
113114

@@ -118,7 +119,7 @@ def create_full_hook_executor
118119

119120
should "parse an app spec from the last successful deployment's directory" do
120121
File.expects(:read).with(File.join(@last_successful_deployment_dir, 'deployment-archive', @app_spec_path))
121-
@hook_executor = create_full_hook_executor
122+
@hook_executor = create_hook_executor
122123
end
123124
end
124125

@@ -131,7 +132,7 @@ def create_full_hook_executor
131132

132133
should "parse an app spec from the most recent deployment's directory" do
133134
File.expects(:read).with(File.join(@most_recent_deployment_dir, 'deployment-archive', @app_spec_path))
134-
@hook_executor = create_full_hook_executor
135+
@hook_executor = create_hook_executor
135136
end
136137
end
137138
end
@@ -152,7 +153,7 @@ def create_full_hook_executor
152153
setup do
153154
@app_spec = {"version" => 0.0, "os" => "linux", "hooks" => {}}
154155
YAML.stubs(:load).returns(@app_spec)
155-
@hook_executor = create_full_hook_executor
156+
@hook_executor = create_hook_executor
156157
end
157158

158159
should "do nothing" do
@@ -169,7 +170,7 @@ def create_full_hook_executor
169170
@app_spec = {"version" => 0.0, "os" => "linux", "hooks" => {'ValidateService'=>[{'location'=>'test'}]}}
170171
YAML.stubs(:load).returns(@app_spec)
171172
@script_location = File.join(@deployment_root_dir, 'deployment-archive', 'test')
172-
@hook_executor = create_full_hook_executor
173+
@hook_executor = create_hook_executor
173174
end
174175

175176
should "not be a noop" do
@@ -241,11 +242,25 @@ def create_full_hook_executor
241242
InstanceAgent::ThreadJoiner.stubs(:new).returns(@thread_joiner)
242243
end
243244

245+
context "extra child environment variables are added" do
246+
setup do
247+
revision_envs = {"TEST_ENVIRONMENT_VARIABLE" => "ONE", "ANOTHER_ENV_VARIABLE" => "TWO"}
248+
@child_env.merge!(revision_envs)
249+
@hook_executor = create_hook_executor(:revision_envs => revision_envs)
250+
end
251+
252+
should "call popen with the environment variables" do
253+
Open3.stubs(:popen3).with(@child_env, @script_location, :pgroup => true).yields([@mock_pipe,@mock_pipe,@mock_pipe,@wait_thr])
254+
@value.stubs(:exitstatus).returns(0)
255+
@hook_executor.execute()
256+
end
257+
end
258+
244259
context 'scripts fail for unknown reason' do
245260
setup do
246261
@app_spec = { "version" => 0.0, "os" => "linux", "hooks" => {'ValidateService'=> [{"location"=>"test", "timeout"=>"30"}]}}
247262
YAML.stubs(:load).returns(@app_spec)
248-
@hook_executor = create_full_hook_executor
263+
@hook_executor = create_hook_executor
249264
@popen_error = Errno::ENOENT
250265
Open3.stubs(:popen3).with(@child_env, @script_location, :pgroup => true).raises(@popen_error, 'su')
251266
end
@@ -262,7 +277,7 @@ def create_full_hook_executor
262277
setup do
263278
@app_spec = { "version" => 0.0, "os" => "linux", "hooks" => {'ValidateService'=> [{"location"=>"test", "timeout"=>"30"}]}}
264279
YAML.stubs(:load).returns(@app_spec)
265-
@hook_executor = create_full_hook_executor
280+
@hook_executor = create_hook_executor
266281
@thread_joiner.expects(:joinOrFail).with(@wait_thr).yields
267282
InstanceAgent::ThreadJoiner.expects(:new).with(30).returns(@thread_joiner)
268283
@wait_thr.stubs(:pid).returns(1234)
@@ -307,7 +322,7 @@ def create_full_hook_executor
307322
Open3.stubs(:popen3).with(@child_env, @script_location, :pgroup => true).yields([@mock_pipe,@mock_pipe,@mock_pipe,@wait_thr])
308323
@app_spec = {"version" => 0.0, "os" => "linux", "hooks" => {'ValidateService'=>[{'location'=>'test', 'timeout'=>"#{timeout}"}]}}
309324
YAML.stubs(:load).returns(@app_spec)
310-
@hook_executor = create_full_hook_executor
325+
@hook_executor = create_hook_executor
311326
end
312327

313328
context "STDOUT left open" do
@@ -341,7 +356,7 @@ def create_full_hook_executor
341356
setup do
342357
@app_spec = { "version" => 0.0, "os" => "linux", "hooks" => {'ValidateService'=> [{"location"=>"test", "runas"=>"user"}]}}
343358
YAML.stubs(:load).returns(@app_spec)
344-
@hook_executor = create_full_hook_executor
359+
@hook_executor = create_hook_executor
345360
mock_pipe = mock
346361
Open3.stubs(:popen3).with(@child_env, 'su user -c ' + @script_location, :pgroup => true).yields([@mock_pipe,@mock_pipe,@mock_pipe,@wait_thr])
347362
end
@@ -374,7 +389,7 @@ def create_full_hook_executor
374389
setup do
375390
@app_spec = { "version" => 0.0, "os" => "linux", "hooks" => {'ValidateService'=> [{"location"=>"test"}]}}
376391
YAML.stubs(:load).returns(@app_spec)
377-
@hook_executor = create_full_hook_executor
392+
@hook_executor = create_hook_executor
378393
Open3.stubs(:popen3).with(@child_env, @script_location, :pgroup => true).yields([@mock_pipe,@mock_pipe,@mock_pipe,@wait_thr])
379394
end
380395

@@ -406,7 +421,7 @@ def create_full_hook_executor
406421
setup do
407422
@app_spec = { "version" => 0.0, "os" => "linux", "hooks" => {'ValidateService'=> [{"location"=>"test"}]}}
408423
YAML.stubs(:load).returns(@app_spec)
409-
@hook_executor = create_full_hook_executor
424+
@hook_executor = create_hook_executor
410425
Open3.stubs(:popen3).with(@child_env, @script_location, {}).yields([@mock_pipe,@mock_pipe,@mock_pipe,@wait_thr])
411426
InstanceAgent::LinuxUtil.stubs(:supports_process_groups?).returns(false)
412427
end

0 commit comments

Comments
 (0)