diff --git a/lib/instance_agent/plugins/codedeploy/installer.rb b/lib/instance_agent/plugins/codedeploy/installer.rb index 0ed61073..b7b37625 100644 --- a/lib/instance_agent/plugins/codedeploy/installer.rb +++ b/lib/instance_agent/plugins/codedeploy/installer.rb @@ -64,7 +64,7 @@ def generate_instructions(application_specification) fi.source) log(:debug, "generating instructions for copying #{fi.source} to #{fi.destination}") - if File.directory?(absolute_source_path) + if File.directory?(absolute_source_path) && !File.symlink?(absolute_source_path) fill_in_missing_ancestors(i, fi.destination) generate_directory_copy(i, absolute_source_path, fi.destination) else @@ -108,7 +108,8 @@ def generate_directory_copy(i, absolute_source_path, destination) absolute_source_path = absolute_source_path.force_encoding("UTF-8"); absolute_entry_path = File.join(absolute_source_path, entry) entry_destination = File.join(destination, entry) - if File.directory?(absolute_entry_path) + + if File.directory?(absolute_entry_path) && !File.symlink?(absolute_entry_path) generate_directory_copy(i, absolute_entry_path, entry_destination) else generate_normal_copy(i, absolute_entry_path, entry_destination) diff --git a/test/instance_agent/plugins/codedeploy/installer_test.rb b/test/instance_agent/plugins/codedeploy/installer_test.rb index 22ddf2e1..49f087c6 100644 --- a/test/instance_agent/plugins/codedeploy/installer_test.rb +++ b/test/instance_agent/plugins/codedeploy/installer_test.rb @@ -255,6 +255,93 @@ class CodeDeployPluginInstallerTest < InstanceAgentTestCase end # "regular files" + context "symbolic links" do + + setup do + @app_spec + .stubs(:files) + .returns([stub(:source => "src1", + :destination => "dst1")]) + + File.stubs(:directory?).returns(false) + File.stubs(:directory?).with("dst1").returns(true) + + File.stubs(:exists?).returns(false) + File.stubs(:exists?).with("dst1").returns(true) + + @command_sequence = sequence("commands") + end + + should "generate a copy command for the source file if it is a symbolic link of a regular file" do + File.stubs(:directory?).with("deploy-archive-dir/src1").returns(false) + File.stubs(:symlink?).with("deploy-archive-dir/src1").returns(true) + + @instruction_builder + .expects(:copy) + .with("deploy-archive-dir/src1", "dst1/src1") + .in_sequence(@command_sequence) + + @installer.install(@deployment_group_id, @app_spec) + end + + should "generate a copy command instead of a mkdir command for the source file if it is a symbolic link of a directory" do + File.stubs(:directory?).with("deploy-archive-dir/src1").returns(true) + File.stubs(:symlink?).with("deploy-archive-dir/src1").returns(true) + + @instruction_builder + .expects(:mkdir) + .with("dst1/src1") + .never + @instruction_builder + .expects(:copy) + .with("deploy-archive-dir/src1", "dst1/src1") + .in_sequence(@command_sequence) + + @installer.install(@deployment_group_id, @app_spec) + end + + should "generate a copy command if the file inside the source directory is a symbolic link of a regular file" do + File.stubs(:directory?).with("deploy-archive-dir/src1").returns(true) + File.stubs(:symlink?).with("deploy-archive-dir/src1").returns(false) + Dir.stubs(:entries) + .with("deploy-archive-dir/src1") + .returns([".", "..", "foo"]) + + File.stubs(:directory?).with("deploy-archive-dir/src1/foo").returns(false) + File.stubs(:symlink?).with("deploy-archive-dir/src1/foo").returns(true) + + @instruction_builder + .expects(:copy) + .with("deploy-archive-dir/src1/foo", "dst1/foo") + .in_sequence(@command_sequence) + + @installer.install(@deployment_group_id, @app_spec) + end + + should "generate a copy command instead of a mkdir command if the file inside the source directory is a symbolic link of a directory" do + File.stubs(:directory?).with("deploy-archive-dir/src1").returns(true) + File.stubs(:symlink?).with("deploy-archive-dir/src1").returns(false) + Dir.stubs(:entries) + .with("deploy-archive-dir/src1") + .returns([".", "..", "foo"]) + + File.stubs(:directory?).with("deploy-archive-dir/src1/foo").returns(true) + File.stubs(:symlink?).with("deploy-archive-dir/src1/foo").returns(true) + + @instruction_builder + .expects(:mkdir) + .with("dst1/foo") + .never + @instruction_builder + .expects(:copy) + .with("deploy-archive-dir/src1/foo", "dst1/foo") + .in_sequence(@command_sequence) + + @installer.install(@deployment_group_id, @app_spec) + end + + end # "symlinks" + context "directories" do setup do