aws-ec2 0.9.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/.gitmodules +0 -0
- data/CHANGELOG.md +11 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +18 -10
- data/LICENSE.txt +1 -1
- data/README.md +74 -7
- data/Rakefile +1 -1
- data/aws-ec2.gemspec +7 -5
- data/lib/aws-ec2.rb +5 -2
- data/lib/aws_ec2/ami.rb +1 -1
- data/lib/aws_ec2/base.rb +34 -1
- data/lib/aws_ec2/cli.rb +20 -1
- data/lib/aws_ec2/command.rb +34 -5
- data/lib/aws_ec2/completer.rb +161 -0
- data/lib/aws_ec2/completer/script.rb +6 -0
- data/lib/aws_ec2/completer/script.sh +10 -0
- data/lib/aws_ec2/config.rb +4 -2
- data/lib/aws_ec2/core.rb +5 -1
- data/lib/aws_ec2/create.rb +11 -8
- data/lib/aws_ec2/create/error_messages.rb +1 -1
- data/lib/aws_ec2/create/params.rb +2 -6
- data/lib/aws_ec2/help/completion.md +22 -0
- data/lib/aws_ec2/help/completion_script.md +3 -0
- data/lib/aws_ec2/profile.rb +26 -19
- data/lib/aws_ec2/script.rb +1 -0
- data/lib/aws_ec2/script/compile.rb +15 -6
- data/lib/aws_ec2/script/compress.rb +62 -0
- data/lib/aws_ec2/script/upload.rb +75 -9
- data/lib/aws_ec2/setting.rb +41 -0
- data/lib/aws_ec2/template.rb +13 -0
- data/lib/aws_ec2/template/context.rb +32 -0
- data/lib/aws_ec2/template/helper.rb +17 -0
- data/lib/aws_ec2/{template_helper → template/helper}/ami_helper.rb +8 -3
- data/lib/aws_ec2/template/helper/core_helper.rb +88 -0
- data/lib/aws_ec2/{template_helper → template/helper}/partial_helper.rb +2 -2
- data/lib/aws_ec2/template/helper/script_helper.rb +53 -0
- data/lib/aws_ec2/template/helper/ssh_key_helper.rb +21 -0
- data/lib/aws_ec2/version.rb +1 -1
- data/spec/lib/cli_spec.rb +14 -0
- data/spec/spec_helper.rb +16 -6
- metadata +54 -14
- data/lib/aws_ec2/template_helper.rb +0 -18
- data/lib/aws_ec2/template_helper/core_helper.rb +0 -98
@@ -3,20 +3,29 @@ require 'fileutils'
|
|
3
3
|
# Class for aws-ec2 compile command
|
4
4
|
class AwsEc2::Script
|
5
5
|
class Compile < AwsEc2::Base
|
6
|
-
include AwsEc2::
|
7
|
-
BUILD_ROOT = "tmp"
|
6
|
+
include AwsEc2::Template
|
8
7
|
|
9
|
-
|
8
|
+
# used in upload
|
9
|
+
def compile_scripts
|
10
10
|
clean
|
11
11
|
compile_folder("scripts")
|
12
|
-
compile_folder("user-data")
|
13
12
|
end
|
14
13
|
|
15
|
-
|
14
|
+
# use in compile cli command
|
15
|
+
def compile_all
|
16
|
+
clean
|
17
|
+
compile_folder("scripts")
|
18
|
+
layout_path = context.layout_path(@options[:layout])
|
19
|
+
compile_folder("user-data", layout_path)
|
20
|
+
end
|
21
|
+
|
22
|
+
def compile_folder(folder, layout_path=false)
|
16
23
|
puts "Compiling app/#{folder}:".colorize(:green)
|
17
24
|
Dir.glob("#{AwsEc2.root}/app/#{folder}/**/*").each do |path|
|
18
25
|
next if File.directory?(path)
|
19
|
-
|
26
|
+
next if path.include?("layouts")
|
27
|
+
|
28
|
+
result = RenderMePretty.result(path, layout: layout_path, context: context)
|
20
29
|
tmp_path = path.sub(%r{.*/app/}, "#{BUILD_ROOT}/app/")
|
21
30
|
puts " #{tmp_path}"
|
22
31
|
FileUtils.mkdir_p(File.dirname(tmp_path))
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
class AwsEc2::Script
|
4
|
+
class Compress < AwsEc2::Base
|
5
|
+
def compress
|
6
|
+
reset
|
7
|
+
puts "Tarballing #{BUILD_ROOT}/app/scripts folder to scripts.tgz"
|
8
|
+
tarball_path = create_tarball
|
9
|
+
save_scripts_info(tarball_path)
|
10
|
+
puts "Tarball created at #{tarball_path}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def create_tarball
|
14
|
+
# https://apple.stackexchange.com/questions/14980/why-are-dot-underscore-files-created-and-how-can-i-avoid-them
|
15
|
+
sh "cd #{BUILD_ROOT}/app && dot_clean ." if system("type dot_clean > /dev/null")
|
16
|
+
|
17
|
+
# https://serverfault.com/questions/110208/different-md5sums-for-same-tar-contents
|
18
|
+
# Using tar czf directly results in a new m5sum each time because the gzip
|
19
|
+
# timestamp is included. So using: tar -c ... | gzip -n
|
20
|
+
sh "cd #{BUILD_ROOT}/app && tar -c scripts | gzip -n > scripts.tgz" # temporary app/scripts.tgz file
|
21
|
+
|
22
|
+
rename_with_md5!
|
23
|
+
end
|
24
|
+
|
25
|
+
def clean
|
26
|
+
FileUtils.rm_f("#{BUILD_ROOT}/scripts/scripts-#{md5sum}.tgz")
|
27
|
+
end
|
28
|
+
|
29
|
+
# Apppend a md5 to file after it's been created and moves it to
|
30
|
+
# output/scripts/scripts-[MD5].tgz
|
31
|
+
def rename_with_md5!
|
32
|
+
md5_path = "#{BUILD_ROOT}/scripts/scripts-#{md5sum}.tgz"
|
33
|
+
FileUtils.mkdir_p(File.dirname(md5_path))
|
34
|
+
FileUtils.mv("#{BUILD_ROOT}/app/scripts.tgz", md5_path)
|
35
|
+
md5_path
|
36
|
+
end
|
37
|
+
|
38
|
+
def save_scripts_info(scripts_name)
|
39
|
+
FileUtils.mkdir_p(File.dirname(SCRIPTS_INFO_PATH))
|
40
|
+
IO.write(SCRIPTS_INFO_PATH, scripts_name)
|
41
|
+
end
|
42
|
+
|
43
|
+
# cache this because the file will get removed
|
44
|
+
def md5sum
|
45
|
+
@md5sum ||= Digest::MD5.file("#{BUILD_ROOT}/app/scripts.tgz").to_s[0..7]
|
46
|
+
end
|
47
|
+
|
48
|
+
def sh(command)
|
49
|
+
puts "=> #{command}"
|
50
|
+
system command
|
51
|
+
end
|
52
|
+
|
53
|
+
# Only avaialble after script has been built.
|
54
|
+
def scripts_name
|
55
|
+
IO.read(SCRIPTS_INFO_PATH).strip
|
56
|
+
end
|
57
|
+
|
58
|
+
def reset
|
59
|
+
FileUtils.rm_f(SCRIPTS_INFO_PATH)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'filesize'
|
2
|
+
require 'aws-sdk-s3'
|
1
3
|
require 'fileutils'
|
2
4
|
|
3
5
|
# Class for aws-ec2 upload command
|
@@ -8,17 +10,77 @@ class AwsEc2::Script
|
|
8
10
|
@compile = @options[:compile] ? @options[:compile] : true
|
9
11
|
end
|
10
12
|
|
11
|
-
def
|
12
|
-
compiler.
|
13
|
-
|
14
|
-
|
13
|
+
def run
|
14
|
+
compiler.compile_scripts if @compile
|
15
|
+
compressor.compress
|
16
|
+
upload(tarball_path)
|
17
|
+
compressor.clean
|
18
|
+
compiler.clean if @compile and AwsEc2.settings["compile_clean"]
|
15
19
|
end
|
16
20
|
|
17
|
-
def
|
18
|
-
puts "Uploading
|
19
|
-
|
20
|
-
|
21
|
-
|
21
|
+
def upload(tarball_path)
|
22
|
+
puts "Uploading scripts.tgz (#{filesize}) to #{s3_dest}"
|
23
|
+
obj = s3_resource.bucket(bucket_name).object(key)
|
24
|
+
start_time = Time.now
|
25
|
+
if @options[:noop]
|
26
|
+
puts "NOOP: Not uploading file to s3"
|
27
|
+
else
|
28
|
+
obj.upload_file(tarball_path)
|
29
|
+
end
|
30
|
+
time_took = pretty_time(Time.now-start_time).colorize(:green)
|
31
|
+
puts "Time to upload code to s3: #{time_took}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def tarball_path
|
35
|
+
IO.read(SCRIPTS_INFO_PATH).strip
|
36
|
+
end
|
37
|
+
|
38
|
+
def filesize
|
39
|
+
Filesize.from(File.size(tarball_path).to_s + " B").pretty
|
40
|
+
end
|
41
|
+
|
42
|
+
def s3_dest
|
43
|
+
"s3://#{bucket_name}/#{key}"
|
44
|
+
end
|
45
|
+
|
46
|
+
def key
|
47
|
+
# Example key: ec2/development/scripts/scripts-md5
|
48
|
+
"#{dest_folder}/#{File.basename(tarball_path)}"
|
49
|
+
end
|
50
|
+
|
51
|
+
# Example:
|
52
|
+
# s3_folder: s3://infra-bucket/ec2
|
53
|
+
# bucket_name: infra-bucket
|
54
|
+
def bucket_name
|
55
|
+
s3_folder.sub('s3://','').split('/').first
|
56
|
+
end
|
57
|
+
|
58
|
+
# Removes s3://bucket-name and adds AwsEc2.env. Example:
|
59
|
+
# s3_folder: s3://infra-bucket/ec2
|
60
|
+
# bucket_name: ec2/development/scripts
|
61
|
+
def dest_folder
|
62
|
+
folder = s3_folder.sub('s3://','').split('/')[1..-1].join('/')
|
63
|
+
"#{folder}/#{AwsEc2.env}/scripts"
|
64
|
+
end
|
65
|
+
|
66
|
+
# s3_folder example:
|
67
|
+
def s3_folder
|
68
|
+
AwsEc2.settings["s3_folder"]
|
69
|
+
end
|
70
|
+
|
71
|
+
def s3_resource
|
72
|
+
@s3_resource ||= Aws::S3::Resource.new
|
73
|
+
end
|
74
|
+
|
75
|
+
# http://stackoverflow.com/questions/4175733/convert-duration-to-hoursminutesseconds-or-similar-in-rails-3-or-ruby
|
76
|
+
def pretty_time(total_seconds)
|
77
|
+
minutes = (total_seconds / 60) % 60
|
78
|
+
seconds = total_seconds % 60
|
79
|
+
if total_seconds < 60
|
80
|
+
"#{seconds.to_i}s"
|
81
|
+
else
|
82
|
+
"#{minutes.to_i}m #{seconds.to_i}s"
|
83
|
+
end
|
22
84
|
end
|
23
85
|
|
24
86
|
def sh(command)
|
@@ -29,5 +91,9 @@ class AwsEc2::Script
|
|
29
91
|
def compiler
|
30
92
|
@compiler ||= Compile.new(@options)
|
31
93
|
end
|
94
|
+
|
95
|
+
def compressor
|
96
|
+
@compressor ||= Compress.new(@options)
|
97
|
+
end
|
32
98
|
end
|
33
99
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module AwsEc2
|
4
|
+
class Setting
|
5
|
+
def initialize(check_project=true)
|
6
|
+
@check_project = check_project
|
7
|
+
end
|
8
|
+
|
9
|
+
# data contains the settings.yml config. The order or precedence for settings
|
10
|
+
# is the project lono/settings.yml and then the ~/.lono/settings.yml.
|
11
|
+
@@data = nil
|
12
|
+
def data
|
13
|
+
return @@data if @@data
|
14
|
+
|
15
|
+
if @check_project && !File.exist?(project_settings_path)
|
16
|
+
puts "ERROR: No settings file at #{project_settings_path}. Are you sure you are in a aws-ec2 project?".colorize(:red)
|
17
|
+
exit 1
|
18
|
+
end
|
19
|
+
|
20
|
+
all_envs = load_file(project_settings_path)
|
21
|
+
@@data = all_envs[AwsEc2.env]
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
def load_file(path)
|
26
|
+
return Hash.new({}) unless File.exist?(path)
|
27
|
+
|
28
|
+
content = RenderMePretty.result(path)
|
29
|
+
data = YAML.load(content)
|
30
|
+
# ensure no nil values
|
31
|
+
data.each do |key, value|
|
32
|
+
data[key] = {} if value.nil?
|
33
|
+
end
|
34
|
+
data
|
35
|
+
end
|
36
|
+
|
37
|
+
def project_settings_path
|
38
|
+
"#{AwsEc2.root}/config/settings.yml"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "active_support" # for autoload
|
2
|
+
require "active_support/core_ext/string"
|
3
|
+
|
4
|
+
module AwsEc2
|
5
|
+
module Template
|
6
|
+
autoload :Context, "aws_ec2/template/context"
|
7
|
+
autoload :Helper, "aws_ec2/template/helper"
|
8
|
+
|
9
|
+
def context
|
10
|
+
@context ||= AwsEc2::Template::Context.new(@options)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "active_support/core_ext/string"
|
2
|
+
|
3
|
+
# Encapsulates helper methods and instance variables to be rendered in the ERB
|
4
|
+
# templates.
|
5
|
+
module AwsEc2::Template
|
6
|
+
class Context
|
7
|
+
include AwsEc2::Template::Helper
|
8
|
+
|
9
|
+
def initialize(options={})
|
10
|
+
@options = options
|
11
|
+
load_custom_helpers
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
# Load custom helper methods from project
|
16
|
+
def load_custom_helpers
|
17
|
+
Dir.glob("#{AwsEc2.root}/app/helpers/**/*_helper.rb").each do |path|
|
18
|
+
filename = path.sub(%r{.*/},'').sub('.rb','')
|
19
|
+
module_name = filename.classify
|
20
|
+
|
21
|
+
# Prepend a period so require works AWS_EC2_ROOT is set to a relative path
|
22
|
+
# without a period.
|
23
|
+
#
|
24
|
+
# Example: AWS_EC2_ROOT=tmp/project
|
25
|
+
first_char = path[0..0]
|
26
|
+
path = "./#{path}" unless %w[. /].include?(first_char)
|
27
|
+
require path
|
28
|
+
self.class.send :include, module_name.constantize
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "active_support/core_ext/string"
|
2
|
+
|
3
|
+
module AwsEc2::Template
|
4
|
+
module Helper
|
5
|
+
def autoinclude(klass)
|
6
|
+
autoload klass, "aws_ec2/template/helper/#{klass.to_s.underscore}"
|
7
|
+
include const_get(klass)
|
8
|
+
end
|
9
|
+
extend self
|
10
|
+
|
11
|
+
autoinclude :AmiHelper
|
12
|
+
autoinclude :CoreHelper
|
13
|
+
autoinclude :PartialHelper
|
14
|
+
autoinclude :ScriptHelper
|
15
|
+
autoinclude :SshKeyHelper
|
16
|
+
end
|
17
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module AwsEc2::
|
1
|
+
module AwsEc2::Template::Helper::AmiHelper
|
2
2
|
include AwsEc2::AwsServices
|
3
3
|
|
4
4
|
# Example:
|
@@ -13,11 +13,16 @@ module AwsEc2::TemplateHelper::AmiHelper
|
|
13
13
|
def latest_ami(query, owners=["self"])
|
14
14
|
images = search_ami(query, owners)
|
15
15
|
image = images.sort_by(&:name).reverse.first
|
16
|
-
image
|
16
|
+
if image
|
17
|
+
image.image_id
|
18
|
+
else
|
19
|
+
puts "latest_ami helper method could not find an AMI with the query of: #{query.inspect}".colorize(:red)
|
20
|
+
exit 1
|
21
|
+
end
|
17
22
|
end
|
18
23
|
|
19
24
|
def search_ami(query, owners=["self"])
|
20
|
-
|
25
|
+
ec2.describe_images(
|
21
26
|
owners: owners,
|
22
27
|
filters: [
|
23
28
|
{name: "name", values: [query]}
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require "base64"
|
2
|
+
require "erb"
|
3
|
+
|
4
|
+
module AwsEc2::Template::Helper::CoreHelper
|
5
|
+
def user_data(name, base64:true, layout:"default")
|
6
|
+
# allow user to specify the path also
|
7
|
+
if File.exist?(name)
|
8
|
+
name = File.basename(name) # normalize name, change path to name
|
9
|
+
end
|
10
|
+
name = File.basename(name, '.sh')
|
11
|
+
|
12
|
+
layout_path = layout_path(layout)
|
13
|
+
path = "#{AwsEc2.root}/app/user-data/#{name}.sh"
|
14
|
+
result = RenderMePretty.result(path, context: self, layout: layout_path)
|
15
|
+
result = append_scripts(result)
|
16
|
+
|
17
|
+
# save the unencoded user-data script for easy debugging
|
18
|
+
temp_path = "#{AwsEc2.root}/tmp/user-data.txt"
|
19
|
+
FileUtils.mkdir_p(File.dirname(temp_path))
|
20
|
+
IO.write(temp_path, result)
|
21
|
+
|
22
|
+
base64 ? Base64.encode64(result).strip : result
|
23
|
+
end
|
24
|
+
|
25
|
+
# Get full path of layout from layout name
|
26
|
+
#
|
27
|
+
# layout_name=false - dont use layout at all
|
28
|
+
# layout_name=nil - default to default.sh layout if available
|
29
|
+
def layout_path(name="default")
|
30
|
+
return false if name == false # disable layout
|
31
|
+
name = "default" if name.nil? # in case user passes in nil
|
32
|
+
|
33
|
+
ext = File.extname(name)
|
34
|
+
name += ".sh" if ext.empty?
|
35
|
+
layout_path = "#{AwsEc2.root}/app/user-data/layouts/#{name}"
|
36
|
+
|
37
|
+
# special rule for default in case there's no default layout
|
38
|
+
if name.include?("default") and !File.exist?(layout_path)
|
39
|
+
return false
|
40
|
+
end
|
41
|
+
|
42
|
+
# other named layouts should error if it doesnt exit
|
43
|
+
unless File.exist?(layout_path)
|
44
|
+
puts "ERROR: Layout #{layout_path} does not exist. Are you sure it exists? Exiting".colorize(:red)
|
45
|
+
exit 1
|
46
|
+
end
|
47
|
+
|
48
|
+
layout_path
|
49
|
+
end
|
50
|
+
|
51
|
+
# provides access to config/* settings as variables
|
52
|
+
# AWS_EC2_ENV=development => config/development.yml
|
53
|
+
# AWS_EC2_ENV=production => config/production.yml
|
54
|
+
def config
|
55
|
+
AwsEc2.config
|
56
|
+
end
|
57
|
+
|
58
|
+
# provides access to config/settings.yml as variables
|
59
|
+
def settings
|
60
|
+
AwsEc2.settings
|
61
|
+
end
|
62
|
+
|
63
|
+
# pretty timestamp that is useful for ami ids.
|
64
|
+
# the timestamp is generated once and cached.
|
65
|
+
def timestamp
|
66
|
+
@timestamp ||= Time.now.strftime("%Y-%m-%d-%H-%M-%S")
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
def append_scripts(user_data)
|
71
|
+
# assuming user-data script is a bash script for simplicity
|
72
|
+
script = AwsEc2::Script.new(@options)
|
73
|
+
user_data += script.auto_terminate if @options[:auto_terminate]
|
74
|
+
user_data += script.create_ami if @options[:ami_name]
|
75
|
+
user_data
|
76
|
+
end
|
77
|
+
|
78
|
+
# Load custom helper methods from the project repo
|
79
|
+
def load_custom_helpers
|
80
|
+
Dir.glob("#{AwsEc2.root}/app/helpers/**/*_helper.rb").each do |path|
|
81
|
+
filename = path.sub(%r{.*/},'').sub('.rb','')
|
82
|
+
module_name = filename.classify
|
83
|
+
|
84
|
+
require path
|
85
|
+
self.class.send :include, module_name.constantize
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module AwsEc2::
|
1
|
+
module AwsEc2::Template::Helper::PartialHelper
|
2
2
|
def partial_exist?(path)
|
3
3
|
path = partial_path_for(path)
|
4
4
|
path = auto_add_format(path)
|
@@ -17,7 +17,7 @@ module AwsEc2::TemplateHelper::PartialHelper
|
|
17
17
|
path = partial_path_for(path)
|
18
18
|
path = auto_add_format(path)
|
19
19
|
|
20
|
-
result =
|
20
|
+
result = RenderMePretty.result(path, context: self)
|
21
21
|
result = indent(result, options[:indent]) if options[:indent]
|
22
22
|
if options[:indent]
|
23
23
|
# Add empty line at beginning because empty lines gets stripped during
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module AwsEc2::Template::Helper::ScriptHelper
|
2
|
+
# Bash code that is meant to included in user-data
|
3
|
+
def extract_scripts(options={})
|
4
|
+
check_s3_folder_settings!
|
5
|
+
|
6
|
+
settings_options = settings["extract_scripts"] || {}
|
7
|
+
options = settings_options.merge(options)
|
8
|
+
# defaults also here in case they are removed from settings
|
9
|
+
to = options[:to] || "/opt"
|
10
|
+
user = options[:as] || "ec2-user"
|
11
|
+
|
12
|
+
if Dir.glob("#{AwsEc2.root}/app/scripts*").empty?
|
13
|
+
puts "WARN: you are using the extract_scripts helper method but you do not have any app/scripts.".colorize(:yellow)
|
14
|
+
calling_line = caller[0].split(':')[0..1].join(':')
|
15
|
+
puts "Called from: #{calling_line}"
|
16
|
+
return ""
|
17
|
+
end
|
18
|
+
|
19
|
+
<<-BASH_CODE
|
20
|
+
# Generated from the aws-ec2 extract_scripts helper.
|
21
|
+
# Downloads scripts from s3, extract them, and setup.
|
22
|
+
mkdir -p #{to}
|
23
|
+
aws s3 cp #{scripts_s3_path} #{to}/
|
24
|
+
(
|
25
|
+
cd #{to}
|
26
|
+
tar zxf #{to}/#{scripts_name}
|
27
|
+
chmod -R a+x #{to}/scripts
|
28
|
+
chown -R #{user}:#{user} #{to}/scripts
|
29
|
+
)
|
30
|
+
BASH_CODE
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
def check_s3_folder_settings!
|
35
|
+
return if settings["s3_folder"]
|
36
|
+
|
37
|
+
puts "Helper method called that requires the s3_folder to be set at:"
|
38
|
+
lines = caller.reject { |l| l =~ %r{lib/aws-ec2} } # hide internal aws-ec2 trace
|
39
|
+
puts " #{lines[0]}"
|
40
|
+
|
41
|
+
puts "Please configure your config/settings.yml with an s3_folder.".colorize(:red)
|
42
|
+
exit 1
|
43
|
+
end
|
44
|
+
|
45
|
+
def scripts_name
|
46
|
+
File.basename(scripts_s3_path)
|
47
|
+
end
|
48
|
+
|
49
|
+
def scripts_s3_path
|
50
|
+
upload = AwsEc2::Script::Upload.new
|
51
|
+
upload.s3_dest
|
52
|
+
end
|
53
|
+
end
|