Skip to content

Commit

Permalink
Merge pull request #260 from aws/v1.1.2
Browse files Browse the repository at this point in the history
V1.1.2
  • Loading branch information
yubangxi authored Jul 31, 2020
2 parents 71cb2c6 + 8bc7f07 commit a0e45b6
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 16 deletions.
2 changes: 1 addition & 1 deletion codedeploy_agent.gemspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Gem::Specification.new do |spec|
spec.name = 'aws_codedeploy_agent'
spec.version = '1.1.1'
spec.version = '1.1.2'
spec.summary = 'Packages AWS CodeDeploy agent libraries'
spec.description = 'AWS CodeDeploy agent is responsible for doing the actual work of deploying software on an individual EC2 instance'
spec.author = 'Amazon Web Services'
Expand Down
12 changes: 1 addition & 11 deletions lib/instance_agent/platform/linux_util.rb
Original file line number Diff line number Diff line change
Expand Up @@ -133,22 +133,12 @@ def self.execute_zip_command(cmd)
log(:debug, "Command status: #{$?}")
log(:debug, "Command output: #{output}")

if !validZipExitStatus(exit_status)
if exit_status != 0
msg = "Error extracting zip archive: #{exit_status}"
log(:error, msg)
raise msg
end
end

private
def self.validZipExitStatus(exit_status)
exit_status == 0 || isWarningStatus(exit_status)
end

private
def self.isWarningStatus(exit_status)
exit_status == 1
end

private
def self.log(severity, message)
Expand Down
2 changes: 1 addition & 1 deletion lib/instance_agent/platform/windows_util.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def self.execute_zip_command(cmd)

if exit_status != 0
msg = "Error extracting zip archive: #{exit_status}"
log(:debug, msg)
log(:error, msg)
raise msg
end
end
Expand Down
5 changes: 2 additions & 3 deletions lib/instance_agent/plugins/codedeploy/command_executor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -384,17 +384,16 @@ def unpack_bundle(cmd, bundle_file, deployment_spec)
begin
InstanceAgent::Platform.util.extract_zip(bundle_file, dst)
rescue
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.")
Zip::File.open(bundle_file) do |zipfile|
zipfile.each do |f|
file_dst = File.join(dst, f.name)
FileUtils.mkdir_p(File.dirname(file_dst))
zipfile.extract(f, file_dst)
zipfile.extract(f, file_dst) { true }
end
end
end
else
# If the bundle was a generated through a Sabini Repository
# it will be in tar format, and it won't have a bundle type
InstanceAgent::Platform.util.extract_tar(bundle_file, dst)
end

Expand Down
121 changes: 121 additions & 0 deletions test/instance_agent/plugins/codedeploy/unpack_bundle_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
require 'test_helper'
require 'certificate_helper'
require 'stringio'
require 'aws/codedeploy/local/deployer'

class UnpackBundleTest < InstanceAgentTestCase
include InstanceAgent::Plugins::CodeDeployPlugin
def generate_signed_message_for(map)
message = @cert_helper.sign_message(map.to_json)
spec = OpenStruct.new({ :payload => message })
spec.format = "PKCS7/JSON"

return spec
end

# method to create a local source bundle file as zip
def setup_local_file_bundle
@local_file_directory = File.join(@root_dir, @deployment_group_id.to_s, 'LocalFileDirectory')
FileUtils.rm_rf(@local_file_directory)
FileUtils.mkdir_p(@local_file_directory)

input_filenames = %w(file1.txt file2.txt)
input_filenames.each do |filename|
File.open(File.join(@local_file_directory, filename), "w") do |f|
f.write("content of #{filename}")
f.close
end
end
# create the bundle as a local zip file
@local_file_location = File.join(@local_file_directory, "bundle.zip")
Zip::File.open(@local_file_location, Zip::File::CREATE) do |zipfile|
input_filenames.each do |filename|
zipfile.add(filename, File.join(@local_file_directory, filename))
end
end
end

context 'The CodeDeploy Plugin Command Executor' do
setup do
@test_hook_mapping = {
"BeforeBlockTraffic"=>["BeforeBlockTraffic"],
"AfterBlockTraffic"=>["AfterBlockTraffic"],
"ApplicationStop"=>["ApplicationStop"],
"BeforeInstall"=>["BeforeInstall"],
"AfterInstall"=>["AfterInstall"],
"ApplicationStart"=>["ApplicationStart"],
"BeforeAllowTraffic"=>["BeforeAllowTraffic"],
"AfterAllowTraffic"=>["AfterAllowTraffic"],
"ValidateService"=>["ValidateService"]
}
@deploy_control_client = mock
@command_executor = InstanceAgent::Plugins::CodeDeployPlugin::CommandExecutor.new(
{
:deploy_control_client => @deploy_control_client,
:hook_mapping => @test_hook_mapping
})
@aws_region = 'us-east-1'
InstanceMetadata.stubs(:region).returns(@aws_region)
end

context "when executing a command" do
setup do
@cert_helper = CertificateHelper.new
@deployment_id = SecureRandom.uuid
@deployment_group_name = "TestDeploymentGroup"
@application_name = "TestApplicationName"
@deployment_group_id = "foobar"
@command = Aws::CodeDeployCommand::Types::HostCommandInstance.new(
:host_command_identifier => "command-1",
:deployment_execution_id => "test-execution")
@root_dir = '/tmp/codedeploy/'
@deployment_root_dir = File.join(@root_dir, @deployment_group_id.to_s, @deployment_id.to_s)
@archive_root_dir = File.join(@deployment_root_dir, 'deployment-archive')
ProcessManager::Config.config[:root_dir] = @root_dir
end

context "test fallback mechanism in unpack_bundle in DownloadBundle" do
setup do
setup_local_file_bundle

# Create a debris file in the deployment-archive directory to simulate Zip::DestinationFileExistsError.
# 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.
# With the ruby unzip overwrite fix, the unpack_bundle should succeed even with debris files.
FileUtils.rm_rf(@archive_root_dir)
FileUtils.mkdir_p(@archive_root_dir)
FileUtils.cp(File.join(@local_file_directory, 'file1.txt'), @archive_root_dir)

# We need to avoid removing @archive_root_dir in the actual logic, to avoid debris file to be deleted.
FileUtils.stubs(:rm_rf).with(@archive_root_dir)
# This exception will let the unpack_bundle method to use the rubyzip fallback mechanism
InstanceAgent::LinuxUtil.expects(:extract_zip)
.with(File.join(@deployment_root_dir, 'bundle.tar'), @archive_root_dir)
.raises("Exception: System unzip throws exception with non-zero exit code")

@command.command_name = 'DownloadBundle'
@bundle_type = 'zip'
@deployment_spec = generate_signed_message_for(
{
"DeploymentId" => @deployment_id.to_s,
"DeploymentGroupId" => @deployment_group_id.to_s,
"ApplicationName" => @application_name,
"DeploymentGroupName" => @deployment_group_name,
"Revision" => {
"RevisionType" => "Local File",
"LocalRevision" => {
"Location" => @local_file_location,
"BundleType" => @bundle_type
}
}
})
end

should 'execute DownloadBundle command with debris file in deployment-archive' do
assert_equal 1, (Dir.entries(@archive_root_dir) - [".", ".."]).size
@command_executor.execute_command(@command, @deployment_spec)
assert_equal 2, (Dir.entries(@archive_root_dir) - [".", ".."]).size
end
end
end
end
end

0 comments on commit a0e45b6

Please sign in to comment.