• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

aws / aws-codedeploy-agent / 4600315001

pending completion
4600315001

push

github

GitHub
Updating latest version info for master branch

1129 of 2362 relevant lines covered (47.8%)

2.1 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

22.92
/lib/instance_agent/plugins/codedeploy/installer.rb
1
require 'instance_agent/plugins/codedeploy/install_instruction'
1✔
2

3
module InstanceAgent
1✔
4
  module Plugins
1✔
5
    module CodeDeployPlugin
1✔
6
      # Manages install and cleanup files.  Also generates and executes
7
      # install instructions based on the files section of the
8
      # application specification file.
9
      class Installer
1✔
10

11
        attr_reader :deployment_archive_dir
1✔
12
        attr_reader :deployment_instructions_dir
1✔
13
        attr_accessor :file_exists_behavior
1✔
14
        def initialize(opts = {})
1✔
15
          raise "the deployment_archive_dir option is required" if
16
          opts[:deployment_archive_dir].nil?
×
17
          raise "the deployment_instructions_dir option is required" if
18
          opts[:deployment_instructions_dir].nil?
×
19
          raise "the file_exists_behavior option is required" if
20
          opts[:file_exists_behavior].nil?
×
21

22
          @deployment_archive_dir = opts[:deployment_archive_dir]
×
23
          @deployment_instructions_dir = opts[:deployment_instructions_dir]
×
24
          @file_exists_behavior = opts[:file_exists_behavior]
×
25
        end
26

27
        def install(deployment_group_id, application_specification)
1✔
28
          cleanup_file = File.join(deployment_instructions_dir, "#{deployment_group_id}-cleanup")
×
29

30
          if File.exists?(cleanup_file)
×
31
            commands = InstanceAgent::Plugins::CodeDeployPlugin::InstallInstruction.parse_remove_commands(File.read(cleanup_file))
×
32
            commands.each do |cmd|
×
33
              cmd.execute
×
34
            end
35

36
            commands.clear
×
37
            FileUtils.rm(cleanup_file)
×
38
          end
39

40
          instructions = generate_instructions(application_specification)
×
41

42
          install_file = File.join(deployment_instructions_dir, "#{deployment_group_id}-install.json")
×
43
          File.open(install_file, "w") do |f|
×
44
            f.write(instructions.to_json)
×
45
          end
46

47
          File.open(cleanup_file, "w") do |f|
×
48
            instructions.command_array.each do |cmd|
×
49
              cmd.execute(f)
×
50
            end
51
          end
52

53
          #Unlink references to the CommandBuilder instance that was yielded to the Proc object(code block) in generate_instructions()
54
          instructions.cleanup
×
55
          instructions = nil
×
56
        end
57

58
        private
1✔
59
        def generate_instructions(application_specification)
1✔
60
          InstanceAgent::Plugins::CodeDeployPlugin::InstallInstruction.generate_instructions() do |i|
×
61
            application_specification.files.each do |fi|
×
62
              absolute_source_path = File.join(deployment_archive_dir, fi.source)
×
63
              file_exists_behavior = application_specification.respond_to?(:file_exists_behavior) && application_specification.file_exists_behavior ? application_specification.file_exists_behavior : @file_exists_behavior
×
64
              log(:debug, "generating instructions for copying #{fi.source} to #{fi.destination}")
×
65
              if File.directory?(absolute_source_path)
×
66
                fill_in_missing_ancestors(i, fi.destination)
×
67
                generate_directory_copy(i, absolute_source_path, fi.destination, file_exists_behavior)
×
68
              else
69
                file_destination = File.join(fi.destination, File.basename(absolute_source_path))
×
70
                fill_in_missing_ancestors(i, file_destination)
×
71
                generate_normal_copy(i, absolute_source_path, file_destination, file_exists_behavior)
×
72
              end
73
            end
74

75
            (application_specification.permissions || []).each do |permission|
×
76
              object = permission.object
×
77

78
              log(:debug, "generating instructions for setting permissions on object #{object}")
×
79
              log(:debug, "it is an existing directory - #{File.directory?(object)}")
×
80
              if i.copying_file?(object)
×
81
                if permission.type.include?("file")
×
82
                  log(:debug, "found matching file #{object} to set permissions on")
×
83
                  permission.validate_file_permission
×
84
                  permission.validate_file_acl(object)
×
85
                  i.set_permissions(object, permission)
×
86
                end
87
              elsif (i.making_directory?(object) || File.directory?(object))
×
88
                log(:debug, "found matching directory #{object} to search for objects to set permissions on")
×
89
                i.find_matches(permission).each do|match|
×
90
                  log(:debug, "found matching object #{match} to set permissions on")
×
91
                  i.set_permissions(match, permission)
×
92
                end
93
              end
94
            end
95
          end
96
        end
97

98
        private
1✔
99
        def generate_directory_copy(i, absolute_source_path, destination, file_exists_behavior)
1✔
100
          unless File.directory?(destination)
×
101
            i.mkdir(destination)
×
102
          end
103

104
          (Dir.entries(absolute_source_path) - [".", ".."]).each do |entry|
×
105
            entry = entry.force_encoding("UTF-8");
×
106
            absolute_source_path = absolute_source_path.force_encoding("UTF-8");
×
107
            absolute_entry_path = File.join(absolute_source_path, entry)
×
108
            entry_destination = File.join(destination, entry)
×
109
            if File.directory?(absolute_entry_path)
×
110
              generate_directory_copy(i, absolute_entry_path, entry_destination, file_exists_behavior)
×
111
            else
112
              generate_normal_copy(i, absolute_entry_path, entry_destination, file_exists_behavior)
×
113
            end
114
          end
115
        end
116

117
        private
1✔
118
        def generate_normal_copy(i, absolute_source_path, destination, file_exists_behavior)
1✔
119
          if File.exists?(destination)
×
120
            case file_exists_behavior
×
121
            when "DISALLOW"
122
              raise "The deployment failed because a specified file already exists at this location: #{destination}"
×
123
            when "OVERWRITE"
124
              i.copy(absolute_source_path, destination)
×
125
            when "RETAIN"
126
              # neither generate copy command or fail the deployment
127
            else
128
              raise "The deployment failed because an invalid option was specified for fileExistsBehavior: #{file_exists_behavior}. Valid options include OVERWRITE, RETAIN, and DISALLOW."
×
129
            end
130
          else
131
            i.copy(absolute_source_path, destination)
×
132
          end
133
        end
134

135
        private
1✔
136
        def fill_in_missing_ancestors(i, destination)
1✔
137
          missing_ancestors = []
×
138
          parent_dir = File.dirname(destination)
×
139
          while !File.exists?(parent_dir) &&
×
140
            parent_dir != "." && parent_dir != "/"
141
            missing_ancestors.unshift(parent_dir)
×
142
            parent_dir = File.dirname(parent_dir)
×
143
          end
144

145
          missing_ancestors.each do |dir|
×
146
            i.mkdir(dir)
×
147
          end
148
        end
149

150
        private
1✔
151
        def description
1✔
152
          self.class.to_s
×
153
        end
154

155
        private
1✔
156
        def log(severity, message)
1✔
157
          raise ArgumentError, "Unknown severity #{severity.inspect}" unless InstanceAgent::Log::SEVERITIES.include?(severity.to_s)
×
158
          InstanceAgent::Log.send(severity.to_sym, "#{description}: #{message}")
×
159
        end
160
      end
161
    end
162
  end
163
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc