Skip to content

Commit

Permalink
Merge pull request #253 from aws/folder_branch
Browse files Browse the repository at this point in the history
If a bundle is an archive of a directory, strip the leading directory
  • Loading branch information
yubangxi authored Jul 9, 2020
2 parents 88f45b1 + f3f033c commit d20ae1d
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 31 deletions.
7 changes: 7 additions & 0 deletions features/codedeploy-local/codedeploy_local.feature
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ Feature: Local Deploy using AWS CodeDeploy Local CLI
And the expected files should have have been locally deployed to my host
And the scripts should have been executed during local deployment

Scenario: Doing a sample local deployment using a zipped_directory bundle
Given I have a sample local zipped_directory bundle
When I create a local deployment with my bundle
Then the local deployment command should succeed
And the expected files should have have been locally deployed to my host
And the scripts should have been executed during local deployment

Scenario: Doing a sample local deployment using a tgz bundle
Given I have a sample local tgz bundle
When I create a local deployment with my bundle
Expand Down
19 changes: 17 additions & 2 deletions features/step_definitions/codedeploy_local_steps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
FileUtils.rm_rf(@test_directory) unless @test_directory.nil?
end

Given(/^I have a sample local (tgz|tar|zip|directory|relative_directory|custom_event_directory|directory_with_destination_files) bundle$/) do |bundle_type|
Given(/^I have a sample local (tgz|tar|zip|zipped_directory|directory|relative_directory|custom_event_directory|directory_with_destination_files) bundle$/) do |bundle_type|
case bundle_type
when 'custom_event_directory'
@bundle_original_directory_location = StepConstants::SAMPLE_CUSTOM_EVENT_APP_BUNDLE_FULL_PATH
Expand All @@ -32,13 +32,15 @@
end

expect(File.directory?(@bundle_original_directory_location)).to be true
@bundle_type = bundle_type.include?('directory') ? 'directory' : bundle_type
@bundle_type = bundle_type.include?('zip') ? 'zip' : (bundle_type.include?('directory') ? 'directory' : bundle_type)

case bundle_type
when 'relative_directory'
@bundle_location = Pathname.new(@bundle_original_directory_location).relative_path_from Pathname.getwd
when 'zip'
@bundle_location = zip_app_bundle(@test_directory)
when 'zipped_directory'
@bundle_location = zip_app_dir_bundle(@test_directory)
when 'tar'
@bundle_location = tar_app_bundle(@test_directory)
when 'tgz'
Expand All @@ -50,6 +52,19 @@
expect(File.file?(@bundle_location)).to be true unless bundle_type.include? 'directory'
end

# Create a zip of the bundle with a nested directory containing the actual bundle files
def zip_app_dir_bundle(temp_directory_to_create_bundle)
zip_file_name = "#{temp_directory_to_create_bundle}/app_dir_bundle.zip"
Dir.mktmpdir { |zip_build_dir|
# Copy the bundle files into a temporary directory so we can just zip the sample bundle
FileUtils.cp_r(StepConstants::SAMPLE_APP_BUNDLE_FULL_PATH, zip_build_dir)
zip_directory(zip_build_dir, zip_file_name)
}
# Confirm appspec.yml is not at top level
Zip::File.open(zip_file_name) { |zip| expect(zip.entries.map(&:name).include? "appspec.yml").to be false }
zip_file_name
end

def tar_app_bundle(temp_directory_to_create_bundle)
tar_file_name = "#{temp_directory_to_create_bundle}/app_bundle.tar"
old_direcory = Dir.pwd
Expand Down
50 changes: 21 additions & 29 deletions lib/instance_agent/plugins/codedeploy/command_executor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -374,16 +374,7 @@ def handle_local_directory(deployment_spec, local_location)

private
def unpack_bundle(cmd, bundle_file, deployment_spec)
strip_leading_directory = deployment_spec.revision_source == 'GitHub'

if strip_leading_directory
# Extract to a temporary directory first so we can move the files around
dst = File.join(deployment_root_dir(deployment_spec), 'deployment-archive-temp')
actual_dst = File.join(deployment_root_dir(deployment_spec), 'deployment-archive')
FileUtils.rm_rf(dst)
else
dst = File.join(deployment_root_dir(deployment_spec), 'deployment-archive')
end
dst = File.join(deployment_root_dir(deployment_spec), 'deployment-archive')

if "tar".eql? deployment_spec.bundle_type
InstanceAgent::Platform.util.extract_tar(bundle_file, dst)
Expand All @@ -407,26 +398,27 @@ def unpack_bundle(cmd, bundle_file, deployment_spec)
InstanceAgent::Platform.util.extract_tar(bundle_file, dst)
end

if strip_leading_directory
log(:info, "Stripping leading directory from archive bundle contents.")

# Find leading directory to remove
archive_root_files = Dir.entries(dst)
archive_root_files.delete_if { |name| name == '.' || name == '..' }
archive_root_files = Dir.entries(dst)
archive_root_files.delete_if { |name| name == '.' || name == '..' }

if (archive_root_files.size != 1)
log(:warn, "Expected archive to have a single root directory containing the actual bundle root, but it had #{archive_root_files.size} entries instead. Skipping leading directory removal and using archive as is.")
FileUtils.mv(dst, actual_dst)
return
end

nested_archive_root = File.join(dst, archive_root_files[0])
log(:debug, "Actual archive root at #{nested_archive_root}. Moving to #{actual_dst}")

FileUtils.mv(nested_archive_root, actual_dst)
FileUtils.rmdir(dst)

log(:debug, Dir.entries(actual_dst).join("; "))
# If the top level of the archive is a directory that contains an appspec,
# strip that before giving up
if ((archive_root_files.size == 1) &&
File.directory?(File.join(dst, archive_root_files[0])) &&
Dir.entries(File.join(dst, archive_root_files[0])).grep(/appspec/i).any?)
log(:info, "Stripping leading directory from archive bundle contents.")
# Move the unpacked files to a temporary location
tmp_dst = File.join(deployment_root_dir(deployment_spec), 'deployment-archive-temp')
FileUtils.rm_rf(tmp_dst)
FileUtils.mv(dst, tmp_dst)

# Move the top level directory to the intended location
nested_archive_root = File.join(tmp_dst, archive_root_files[0])
log(:debug, "Actual archive root at #{nested_archive_root}. Moving to #{dst}")
FileUtils.mv(nested_archive_root, dst)
FileUtils.rmdir(tmp_dst)

log(:debug, Dir.entries(dst).join("; "))
end
end

Expand Down

0 comments on commit d20ae1d

Please sign in to comment.