Class: Dpl::Providers::Elasticbeanstalk

Inherits:
Dpl::Provider show all
Defined in:
lib/dpl/providers/elasticbeanstalk.rb

Constant Summary collapse

NON_PRINTABLE_CHARS =

We do not actually know what characters are valid on AWS EB’s side, see: github.com/aws/aws-sdk-ruby/issues/1502

Reference: www.w3.org/TR/xml/#charsets

"\u0009\u000A\u000D\u0020-\uD7FF\uE000-\uFFFD\u10000-\u10FFFF"

Constants inherited from Dpl::Provider

Dpl::Provider::FOLDS, Dpl::Provider::STAGES

Instance Attribute Summary collapse

Attributes inherited from Dpl::Provider

#key_name, #repo_name

Instance Method Summary collapse

Methods inherited from Dpl::Provider

#before_finish, #before_init, #before_install, #before_prepare, #before_setup, #chmod, #cleanup, #cmd, #compact, #err, #error, #escape, examples, #expand, #file?, #finish?, #fold, #fold?, #info, #initialize, install_deps, install_deps?, #mkdir_p, move_files, #msg, #mv, #only, #open, #opt_for, #opt_key, #opts_for, #print, #quote, #read, #remove_dpl_dir, #rm_rf, #run, #run_cmd, #run_cmds, #run_stage, #run_stage?, #script, #setup_dpl_dir, #setup_git_config, #setup_git_http_user_agent, #setup_git_ssh, #setup_ssh_key, #shell, #sq, #ssh_keygen, #symbolize, #try_ssh_access, #uncleanup, unmove_files, validate_runtimes, #wait_for_ssh_access, #warn

Methods included from Dpl::Provider::Dsl

#apt, #apt?, #cmds, #env, #errs, #full_name, #gem, #gem?, #keep, #move, #msgs, #needs, #needs?, #node_js, #npm, #npm?, #opt, #path, #pip, #pip?, #python, #ruby_pre?, #ruby_version, #runtimes, #status, #strs, #summary, #user_agent, #vars

Methods included from Squiggle

#sq

Methods included from Assets

#asset

Methods included from Env

included, #opts

Methods included from ConfigFile

included, #opts

Methods included from Interpolate

#interpolate, #obfuscate, #vars

Methods included from Memoize

included

Constructor Details

This class inherits a constructor from Dpl::Provider

Instance Attribute Details

#objectObject (readonly)

Returns the value of attribute object.



51
52
53
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 51

def object
  @object
end

#startedObject (readonly)

Returns the value of attribute started.



51
52
53
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 51

def started
  @started
end

#versionObject (readonly)

Returns the value of attribute version.



51
52
53
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 51

def version
  @version
end

Instance Method Details

#archive_nameObject



75
76
77
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 75

def archive_name
  "#{label}.zip"
end

#bucketObject



184
185
186
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 184

def bucket
  @bucket ||= s3.bucket(super)
end

#bucket_pathObject



87
88
89
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 87

def bucket_path
  bucket_path? ? "#{super.gsub(%r{/*$}, '')}/#{archive_name}" : archive_name
end

#check_deployment(msgs) ⇒ Object



141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 141

def check_deployment(msgs)
  sleep 5
  events.each do |event|
    msg = "#{event.event_date} [#{event.severity}] #{event.message}"
    error "Deployment failed: #{msg}" if event.severity == 'ERROR'
    info msg unless msgs.include?(msg)
    msgs << msg
  end
  environment[:status] == 'Ready'
rescue Aws::Errors::ServiceError => e
  info "Caught #{e}: #{e.message}. Retrying ..."
end

#clean(str) ⇒ Object



198
199
200
201
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 198

def clean(str)
  str.gsub!(/[^#{NON_PRINTABLE_CHARS}]/, '') && info(:clean_description)
  str
end

#create_versionObject



114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 114

def create_version
  @version = eb.create_application_version(
    application_name: app,
    version_label: label,
    description: clean(description[0, 200]),
    source_bundle: {
      s3_bucket: bucket.name,
      s3_key: object.key
    },
    auto_create_application: false
  )
end

#create_zipObject



99
100
101
102
103
104
105
106
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 99

def create_zip
  ::Zip::File.open(zip_file, ::Zip::File::CREATE) do |zip|
    files.each do |path|
      debug :zip_add, path
      zip.add(path.sub(cwd, ''), path)
    end
  end
end

#credentialsObject



176
177
178
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 176

def credentials
  Aws::Credentials.new(access_key_id, secret_access_key)
end

#cwdObject



91
92
93
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 91

def cwd
  @cwd ||= "#{Dir.pwd}/"
end

#debug(*args) ⇒ Object



203
204
205
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 203

def debug(*args)
  info(*args) if debug?
end

#deployObject



62
63
64
65
66
67
68
69
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 62

def deploy
  @started = Time.now
  bucket.create unless bucket.exists?
  create_zip unless zip_exists?
  upload
  create_version
  update_app if env?
end

#descriptionObject



83
84
85
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 83

def description
  super || git_commit_msg
end

#ebObject



188
189
190
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 188

def eb
  @eb ||= Aws::ElasticBeanstalk::Client.new(retry_limit: 10)
end

#environmentObject



171
172
173
174
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 171

def environment
  args = { application_name: app, environment_names: [env] }
  eb.describe_environments(args)[:environments].first
end

#eventsObject



166
167
168
169
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 166

def events
  args = { environment_name: env, start_time: started.utc.iso8601 }
  eb.describe_events(args)[:events].reverse
end

#filesObject



154
155
156
157
158
159
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 154

def files
  files = Dir.glob('**/*', File::FNM_DOTMATCH)
  ignore = %w[.ebignore .gitignore].detect { |file| file?(file) }
  files = filter(files, ignore) if ignore
  files
end

#filter(files, spec) ⇒ Object



161
162
163
164
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 161

def filter(files, spec)
  spec = PathSpec.from_filename(spec)
  files.reject { |file| spec.match(file) }
end

#labelObject



79
80
81
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 79

def label
  @label ||= super || "travis-#{git_sha}-#{Time.now.to_i}"
end

#loginObject



53
54
55
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 53

def 
  info :login
end

#s3Object



180
181
182
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 180

def s3
  @s3 ||= Aws::S3::Resource.new
end

#setupObject



57
58
59
60
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 57

def setup
  info :login
  Aws.config.update(credentials:, region:)
end

#update_appObject



127
128
129
130
131
132
133
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 127

def update_app
  eb.update_environment(
    environment_name: env,
    version_label: version[:application_version][:version_label]
  )
  wait_until_deployed if wait_until_deployed?
end

#uploadObject



108
109
110
111
112
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 108

def upload
  @object = bucket.object(bucket_path)
  object.put(body: File.open(zip_file))
  sleep 5 # s3 eventual consistency
end

#wait_until_deployedObject



135
136
137
138
139
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 135

def wait_until_deployed
  msgs = []
  1.upto(wait_until_deployed_timeout / 5) { return if check_deployment(msgs) }
  error 'Deploy status unknown due to timeout. Increase the wait_until_deployed_timeout option'
end

#zip_exists?Boolean

Returns:

  • (Boolean)


95
96
97
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 95

def zip_exists?
  File.exist?(zip_file)
end

#zip_fileObject



71
72
73
# File 'lib/dpl/providers/elasticbeanstalk.rb', line 71

def zip_file
  zip_file? ? expand(super) : archive_name
end