Skip to content

Commit a0e45b6

Browse files
authored
Merge pull request #260 from aws/v1.1.2
V1.1.2
2 parents 71cb2c6 + 8bc7f07 commit a0e45b6

File tree

5 files changed

+126
-16
lines changed

5 files changed

+126
-16
lines changed

codedeploy_agent.gemspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Gem::Specification.new do |spec|
22
spec.name = 'aws_codedeploy_agent'
3-
spec.version = '1.1.1'
3+
spec.version = '1.1.2'
44
spec.summary = 'Packages AWS CodeDeploy agent libraries'
55
spec.description = 'AWS CodeDeploy agent is responsible for doing the actual work of deploying software on an individual EC2 instance'
66
spec.author = 'Amazon Web Services'

lib/instance_agent/platform/linux_util.rb

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -133,22 +133,12 @@ def self.execute_zip_command(cmd)
133133
log(:debug, "Command status: #{$?}")
134134
log(:debug, "Command output: #{output}")
135135

136-
if !validZipExitStatus(exit_status)
136+
if exit_status != 0
137137
msg = "Error extracting zip archive: #{exit_status}"
138138
log(:error, msg)
139139
raise msg
140140
end
141141
end
142-
143-
private
144-
def self.validZipExitStatus(exit_status)
145-
exit_status == 0 || isWarningStatus(exit_status)
146-
end
147-
148-
private
149-
def self.isWarningStatus(exit_status)
150-
exit_status == 1
151-
end
152142

153143
private
154144
def self.log(severity, message)

lib/instance_agent/platform/windows_util.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def self.execute_zip_command(cmd)
100100

101101
if exit_status != 0
102102
msg = "Error extracting zip archive: #{exit_status}"
103-
log(:debug, msg)
103+
log(:error, msg)
104104
raise msg
105105
end
106106
end

lib/instance_agent/plugins/codedeploy/command_executor.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -384,17 +384,16 @@ def unpack_bundle(cmd, bundle_file, deployment_spec)
384384
begin
385385
InstanceAgent::Platform.util.extract_zip(bundle_file, dst)
386386
rescue
387+
log(:warn, "Encountered non-zero exit code with default system unzip util. Hence falling back to ruby unzip to mitigate any partially unzipped or skipped zip files.")
387388
Zip::File.open(bundle_file) do |zipfile|
388389
zipfile.each do |f|
389390
file_dst = File.join(dst, f.name)
390391
FileUtils.mkdir_p(File.dirname(file_dst))
391-
zipfile.extract(f, file_dst)
392+
zipfile.extract(f, file_dst) { true }
392393
end
393394
end
394395
end
395396
else
396-
# If the bundle was a generated through a Sabini Repository
397-
# it will be in tar format, and it won't have a bundle type
398397
InstanceAgent::Platform.util.extract_tar(bundle_file, dst)
399398
end
400399

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
require 'test_helper'
2+
require 'certificate_helper'
3+
require 'stringio'
4+
require 'aws/codedeploy/local/deployer'
5+
6+
class UnpackBundleTest < InstanceAgentTestCase
7+
include InstanceAgent::Plugins::CodeDeployPlugin
8+
def generate_signed_message_for(map)
9+
message = @cert_helper.sign_message(map.to_json)
10+
spec = OpenStruct.new({ :payload => message })
11+
spec.format = "PKCS7/JSON"
12+
13+
return spec
14+
end
15+
16+
# method to create a local source bundle file as zip
17+
def setup_local_file_bundle
18+
@local_file_directory = File.join(@root_dir, @deployment_group_id.to_s, 'LocalFileDirectory')
19+
FileUtils.rm_rf(@local_file_directory)
20+
FileUtils.mkdir_p(@local_file_directory)
21+
22+
input_filenames = %w(file1.txt file2.txt)
23+
input_filenames.each do |filename|
24+
File.open(File.join(@local_file_directory, filename), "w") do |f|
25+
f.write("content of #{filename}")
26+
f.close
27+
end
28+
end
29+
# create the bundle as a local zip file
30+
@local_file_location = File.join(@local_file_directory, "bundle.zip")
31+
Zip::File.open(@local_file_location, Zip::File::CREATE) do |zipfile|
32+
input_filenames.each do |filename|
33+
zipfile.add(filename, File.join(@local_file_directory, filename))
34+
end
35+
end
36+
end
37+
38+
context 'The CodeDeploy Plugin Command Executor' do
39+
setup do
40+
@test_hook_mapping = {
41+
"BeforeBlockTraffic"=>["BeforeBlockTraffic"],
42+
"AfterBlockTraffic"=>["AfterBlockTraffic"],
43+
"ApplicationStop"=>["ApplicationStop"],
44+
"BeforeInstall"=>["BeforeInstall"],
45+
"AfterInstall"=>["AfterInstall"],
46+
"ApplicationStart"=>["ApplicationStart"],
47+
"BeforeAllowTraffic"=>["BeforeAllowTraffic"],
48+
"AfterAllowTraffic"=>["AfterAllowTraffic"],
49+
"ValidateService"=>["ValidateService"]
50+
}
51+
@deploy_control_client = mock
52+
@command_executor = InstanceAgent::Plugins::CodeDeployPlugin::CommandExecutor.new(
53+
{
54+
:deploy_control_client => @deploy_control_client,
55+
:hook_mapping => @test_hook_mapping
56+
})
57+
@aws_region = 'us-east-1'
58+
InstanceMetadata.stubs(:region).returns(@aws_region)
59+
end
60+
61+
context "when executing a command" do
62+
setup do
63+
@cert_helper = CertificateHelper.new
64+
@deployment_id = SecureRandom.uuid
65+
@deployment_group_name = "TestDeploymentGroup"
66+
@application_name = "TestApplicationName"
67+
@deployment_group_id = "foobar"
68+
@command = Aws::CodeDeployCommand::Types::HostCommandInstance.new(
69+
:host_command_identifier => "command-1",
70+
:deployment_execution_id => "test-execution")
71+
@root_dir = '/tmp/codedeploy/'
72+
@deployment_root_dir = File.join(@root_dir, @deployment_group_id.to_s, @deployment_id.to_s)
73+
@archive_root_dir = File.join(@deployment_root_dir, 'deployment-archive')
74+
ProcessManager::Config.config[:root_dir] = @root_dir
75+
end
76+
77+
context "test fallback mechanism in unpack_bundle in DownloadBundle" do
78+
setup do
79+
setup_local_file_bundle
80+
81+
# Create a debris file in the deployment-archive directory to simulate Zip::DestinationFileExistsError.
82+
# This error will be thrown, if the ruby unzip overwrite option is not enabled and when the @archive_root_dir already has the same file.
83+
# With the ruby unzip overwrite fix, the unpack_bundle should succeed even with debris files.
84+
FileUtils.rm_rf(@archive_root_dir)
85+
FileUtils.mkdir_p(@archive_root_dir)
86+
FileUtils.cp(File.join(@local_file_directory, 'file1.txt'), @archive_root_dir)
87+
88+
# We need to avoid removing @archive_root_dir in the actual logic, to avoid debris file to be deleted.
89+
FileUtils.stubs(:rm_rf).with(@archive_root_dir)
90+
# This exception will let the unpack_bundle method to use the rubyzip fallback mechanism
91+
InstanceAgent::LinuxUtil.expects(:extract_zip)
92+
.with(File.join(@deployment_root_dir, 'bundle.tar'), @archive_root_dir)
93+
.raises("Exception: System unzip throws exception with non-zero exit code")
94+
95+
@command.command_name = 'DownloadBundle'
96+
@bundle_type = 'zip'
97+
@deployment_spec = generate_signed_message_for(
98+
{
99+
"DeploymentId" => @deployment_id.to_s,
100+
"DeploymentGroupId" => @deployment_group_id.to_s,
101+
"ApplicationName" => @application_name,
102+
"DeploymentGroupName" => @deployment_group_name,
103+
"Revision" => {
104+
"RevisionType" => "Local File",
105+
"LocalRevision" => {
106+
"Location" => @local_file_location,
107+
"BundleType" => @bundle_type
108+
}
109+
}
110+
})
111+
end
112+
113+
should 'execute DownloadBundle command with debris file in deployment-archive' do
114+
assert_equal 1, (Dir.entries(@archive_root_dir) - [".", ".."]).size
115+
@command_executor.execute_command(@command, @deployment_spec)
116+
assert_equal 2, (Dir.entries(@archive_root_dir) - [".", ".."]).size
117+
end
118+
end
119+
end
120+
end
121+
end

0 commit comments

Comments
 (0)