Class: OpsworksShip::Deploy
- Inherits:
-
Object
- Object
- OpsworksShip::Deploy
- Defined in:
- lib/opsworks_ship/deploy.rb
Instance Method Summary collapse
- #all_stack_names ⇒ Object
- #app_id(stack_id) ⇒ Object
- #deploy ⇒ Object
- #deploy_command ⇒ Object
- #deploy_comment ⇒ Object
- #deployed_by ⇒ Object
- #describe_deployments(deployment_id) ⇒ Object
-
#initialize(stack_name, revision, app_type, app_layer_name_regex, hipchat_auth_token = nil, hipchat_room_id = nil) ⇒ Deploy
constructor
A new instance of Deploy.
- #layer_instance_ids(layer_ids) ⇒ Object
- #monitor_deployment(deployment_id) ⇒ Object
- #opsworks_app_types ⇒ Object
- #post_deployment_to_hipchat(msg) ⇒ Object
- #relevant_app_layer_ids(stack_id) ⇒ Object
- #relevant_instance_ids(stack_id) ⇒ Object
- #set_revision_in_opsworks_app ⇒ Object
- #stack_data ⇒ Object
- #stack_id ⇒ Object
- #stack_layers(stack_id) ⇒ Object
- #start_deployment ⇒ Object
- #syntax ⇒ Object
- #timestamped_puts(str) ⇒ Object
Constructor Details
#initialize(stack_name, revision, app_type, app_layer_name_regex, hipchat_auth_token = nil, hipchat_room_id = nil) ⇒ Deploy
Returns a new instance of Deploy.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# File 'lib/opsworks_ship/deploy.rb', line 5 def initialize(stack_name, revision, app_type, app_layer_name_regex, hipchat_auth_token = nil, hipchat_room_id = nil) @stack_name = stack_name raise "Invalid stack name, valid stacks are: #{all_stack_names}" unless all_stack_names.any?{|available_name| available_name == stack_name} @revision = revision @app_type = app_type raise "Invalid app type #{@app_type}" unless opsworks_app_types.include?(@app_type) @app_layer_name_regex = app_layer_name_regex @hipchat_auth_token = hipchat_auth_token @hipchat_room_id = hipchat_room_id raise "Must supply both or neither hipchat params" if [@hipchat_auth_token, @hipchat_room_id].compact.size == 1 end |
Instance Method Details
#all_stack_names ⇒ Object
52 53 54 |
# File 'lib/opsworks_ship/deploy.rb', line 52 def all_stack_names @all_stack_names ||= stack_data.map{|s| s['Name']}.sort end |
#app_id(stack_id) ⇒ Object
78 79 80 |
# File 'lib/opsworks_ship/deploy.rb', line 78 def app_id(stack_id) JSON.parse(`aws opsworks describe-apps --stack-id=#{stack_id}`)['Apps'].select{|a| a['Type'] == @app_type}.first['AppId'] end |
#deploy ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/opsworks_ship/deploy.rb', line 27 def deploy start_time = Time.now puts "\n-------------------------------------" puts "Deployment started" puts "Revision: #{@revision}" puts "Stack: #{@stack_name}" puts "-------------------------------------\n\n" set_revision_in_opsworks_app deployment_id = start_deployment final_status = monitor_deployment(deployment_id) if final_status.downcase =~ /successful/ msg = "#{@app_type} deployment successful! Layers #{@app_layer_name_regex} now on #{@revision} deployed to #{@stack_name} by #{deployed_by}" post_deployment_to_hipchat(msg) else raise "Deployment failed, status: #{final_status}" end run_time_seconds = Time.now.to_i - start_time.to_i "Deployment time #{run_time_seconds / 60}:%02i" % (run_time_seconds % 60) end |
#deploy_command ⇒ Object
96 97 98 |
# File 'lib/opsworks_ship/deploy.rb', line 96 def deploy_command { :Name => "deploy" }.to_json.gsub('"', "\\\"") end |
#deploy_comment ⇒ Object
92 93 94 |
# File 'lib/opsworks_ship/deploy.rb', line 92 def deploy_comment "--comment \"rev. #{@revision}, deployed by #{deployed_by}\" " end |
#deployed_by ⇒ Object
86 87 88 89 90 |
# File 'lib/opsworks_ship/deploy.rb', line 86 def deployed_by git_user = `git config --global user.name`.chomp git_email = `git config --global user.email`.chomp "#{git_user} (#{git_email})" end |
#describe_deployments(deployment_id) ⇒ Object
117 118 119 120 |
# File 'lib/opsworks_ship/deploy.rb', line 117 def describe_deployments(deployment_id) cmd = "aws opsworks describe-deployments --deployment-ids #{deployment_id}" JSON.parse(`#{cmd}`) end |
#layer_instance_ids(layer_ids) ⇒ Object
161 162 163 164 165 |
# File 'lib/opsworks_ship/deploy.rb', line 161 def layer_instance_ids(layer_ids) layer_ids.map do |layer_id| JSON.parse(`aws opsworks describe-instances --layer-id=#{layer_id}`)['Instances'].map{|i| i['InstanceId']} end.flatten end |
#monitor_deployment(deployment_id) ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/opsworks_ship/deploy.rb', line 100 def monitor_deployment(deployment_id) deployment_finished = false status = "" while !deployment_finished response = describe_deployments(deployment_id) response["Deployments"].each do |deployment| next if deployment["DeploymentId"] != deployment_id status = deployment["Status"] "Status: #{status}" deployment_finished = true if deployment["Status"].downcase != "running" end sleep(15) unless deployment_finished end "Deployment #{status}" status end |
#opsworks_app_types ⇒ Object
179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/opsworks_ship/deploy.rb', line 179 def opsworks_app_types [ 'aws-flow-ruby', 'java', 'rails', 'php', 'nodejs', 'static', 'other', ] end |
#post_deployment_to_hipchat(msg) ⇒ Object
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/opsworks_ship/deploy.rb', line 138 def post_deployment_to_hipchat(msg) room_id = (@hipchat_room_id || ENV['HIPCHAT_ROOM_ID']).to_i auth_token = @hipchat_auth_token || ENV['HIPCHAT_AUTH_TOKEN'] return unless room_id > 0 && auth_token post_data = { :name => "Deployments", :privacy => 'private', :is_archived => false, :is_guest_accessible => true, :topic => 'curl', :message => msg, :color => 'green', :owner => { :id => 5 } } url = "https://api.hipchat.com/v2/room/#{room_id}/notification" cmd = "curl --header \"content-type: application/json\" --header \"Authorization: Bearer #{auth_token}\" -X POST -d \"#{post_data.to_json.gsub('"', '\\"')}\" #{url}" puts cmd `#{cmd}` end |
#relevant_app_layer_ids(stack_id) ⇒ Object
171 172 173 |
# File 'lib/opsworks_ship/deploy.rb', line 171 def relevant_app_layer_ids(stack_id) stack_layers(stack_id).select{|l| l['Name'] =~ /#{@app_layer_name_regex}/i}.map{|layer_data| layer_data['LayerId']} end |
#relevant_instance_ids(stack_id) ⇒ Object
167 168 169 |
# File 'lib/opsworks_ship/deploy.rb', line 167 def relevant_instance_ids(stack_id) layer_instance_ids(relevant_app_layer_ids(stack_id)) end |
#set_revision_in_opsworks_app ⇒ Object
71 72 73 74 75 76 |
# File 'lib/opsworks_ship/deploy.rb', line 71 def set_revision_in_opsworks_app "Setting revision #{@revision}" cmd = "aws opsworks update-app --app-id #{app_id(stack_id)} --app-source Revision=#{@revision}" "#{cmd}" `#{cmd}` end |
#stack_data ⇒ Object
56 57 58 59 60 |
# File 'lib/opsworks_ship/deploy.rb', line 56 def stack_data @stack_data ||= begin JSON.parse(`aws opsworks describe-stacks`)['Stacks'] end end |
#stack_id ⇒ Object
62 63 64 65 66 67 68 69 |
# File 'lib/opsworks_ship/deploy.rb', line 62 def stack_id stack = stack_data.select{|s| s['Name'].downcase == @stack_name.downcase}.first if stack stack['StackId'] else raise "Stack not found. Available opsworks stacks: #{all_stack_names}" end end |
#stack_layers(stack_id) ⇒ Object
175 176 177 |
# File 'lib/opsworks_ship/deploy.rb', line 175 def stack_layers(stack_id) JSON.parse(`aws opsworks describe-layers --stack-id=#{stack_id}`)['Layers'] end |
#start_deployment ⇒ Object
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/opsworks_ship/deploy.rb', line 122 def start_deployment app_id = app_id(stack_id) cmd = "aws opsworks create-deployment --app-id #{app_id} " + "--stack-id #{stack_id} " + "--command \"#{deploy_command}\" " + "--instance-ids #{relevant_instance_ids(stack_id).join(' ')} " + deploy_comment "Starting deployment..." cmd response = JSON.parse(`#{cmd}`) response["DeploymentId"] end |
#syntax ⇒ Object
21 22 23 24 25 |
# File 'lib/opsworks_ship/deploy.rb', line 21 def syntax puts "Arguments: #{method(:initialize).parameters.map{|p| "#{p.last} (#{p.first})"}.join(' ')}" puts "\n" puts "Valid stacks: #{all_stack_names}}" end |
#timestamped_puts(str) ⇒ Object
82 83 84 |
# File 'lib/opsworks_ship/deploy.rb', line 82 def (str) puts "#{Time.now} #{str}" end |