broadside 2.0.0 → 3.0.0.pre.prerelease
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitmodules +0 -3
- data/.hound.yml +2 -0
- data/.rubocop.yml +1080 -0
- data/CHANGELOG.md +41 -3
- data/README.md +54 -66
- data/bin/broadside +2 -174
- data/broadside.gemspec +6 -6
- data/lib/broadside.rb +32 -22
- data/lib/broadside/command.rb +130 -0
- data/lib/broadside/configuration/aws_configuration.rb +25 -0
- data/lib/broadside/configuration/configuration.rb +74 -0
- data/lib/broadside/configuration/invalid_configuration.rb +9 -0
- data/lib/broadside/deploy.rb +7 -99
- data/lib/broadside/ecs/ecs_deploy.rb +114 -179
- data/lib/broadside/ecs/ecs_manager.rb +68 -24
- data/lib/broadside/error.rb +3 -8
- data/lib/broadside/gli/commands.rb +147 -0
- data/lib/broadside/gli/global.rb +72 -0
- data/lib/broadside/logging_utils.rb +9 -0
- data/lib/broadside/target.rb +59 -73
- data/lib/broadside/version.rb +1 -1
- metadata +43 -28
- data/lib/broadside/configuration.rb +0 -58
- data/lib/broadside/configuration/aws_config.rb +0 -14
- data/lib/broadside/configuration/ecs_config.rb +0 -13
- data/lib/broadside/configuration/verify_instance_variables.rb +0 -11
- data/lib/broadside/predeploy_commands.rb +0 -7
- data/lib/broadside/utils.rb +0 -27
@@ -1,12 +1,9 @@
|
|
1
|
-
require 'active_support/core_ext/hash'
|
2
|
-
require 'active_support/core_ext/array'
|
3
|
-
|
4
1
|
module Broadside
|
5
2
|
class EcsManager
|
6
3
|
DEFAULT_DESIRED_COUNT = 0
|
7
4
|
|
8
5
|
class << self
|
9
|
-
include
|
6
|
+
include LoggingUtils
|
10
7
|
|
11
8
|
def ecs
|
12
9
|
@ecs_client ||= Aws::ECS::Client.new(
|
@@ -15,14 +12,14 @@ module Broadside
|
|
15
12
|
)
|
16
13
|
end
|
17
14
|
|
18
|
-
def create_service(cluster, name,
|
15
|
+
def create_service(cluster, name, service_config = {})
|
19
16
|
ecs.create_service(
|
20
17
|
{
|
21
18
|
cluster: cluster,
|
22
19
|
desired_count: DEFAULT_DESIRED_COUNT,
|
23
20
|
service_name: name,
|
24
21
|
task_definition: name
|
25
|
-
}.deep_merge(
|
22
|
+
}.deep_merge(service_config)
|
26
23
|
)
|
27
24
|
end
|
28
25
|
|
@@ -35,42 +32,61 @@ module Broadside
|
|
35
32
|
end
|
36
33
|
|
37
34
|
def get_latest_task_definition(name)
|
38
|
-
return nil unless get_latest_task_definition_arn(name)
|
39
|
-
ecs.describe_task_definition(task_definition:
|
35
|
+
return nil unless (arn = get_latest_task_definition_arn(name))
|
36
|
+
ecs.describe_task_definition(task_definition: arn).task_definition.to_h
|
40
37
|
end
|
41
38
|
|
42
39
|
def get_latest_task_definition_arn(name)
|
43
40
|
get_task_definition_arns(name).last
|
44
41
|
end
|
45
42
|
|
43
|
+
def get_running_instance_ips!(cluster, family, task_arns = nil)
|
44
|
+
ips = get_running_instance_ips(cluster, family, task_arns)
|
45
|
+
raise Error, "No running tasks found for '#{family}' on cluster '#{cluster}'!" if ips.empty?
|
46
|
+
ips
|
47
|
+
end
|
48
|
+
|
46
49
|
def get_running_instance_ips(cluster, family, task_arns = nil)
|
47
50
|
task_arns = task_arns ? Array.wrap(task_arns) : get_task_arns(cluster, family)
|
48
|
-
|
51
|
+
return [] if task_arns.empty?
|
49
52
|
|
50
53
|
tasks = ecs.describe_tasks(cluster: cluster, tasks: task_arns).tasks
|
51
54
|
container_instances = ecs.describe_container_instances(
|
52
55
|
cluster: cluster,
|
53
|
-
container_instances: tasks.map(&:container_instance_arn)
|
56
|
+
container_instances: tasks.map(&:container_instance_arn)
|
54
57
|
).container_instances
|
55
|
-
ec2_instance_ids = container_instances.map(&:ec2_instance_id)
|
56
58
|
|
59
|
+
ec2_instance_ids = container_instances.map(&:ec2_instance_id)
|
57
60
|
reservations = ec2_client.describe_instances(instance_ids: ec2_instance_ids).reservations
|
58
|
-
|
59
|
-
instances.map(&:private_ip_address)
|
61
|
+
|
62
|
+
reservations.map(&:instances).flatten.map(&:private_ip_address)
|
60
63
|
end
|
61
64
|
|
62
|
-
def get_task_arns(cluster, family)
|
63
|
-
|
65
|
+
def get_task_arns(cluster, family, filter = {})
|
66
|
+
options = {
|
67
|
+
cluster: cluster,
|
68
|
+
# Strange AWS restriction requires absence of family if service_name specified
|
69
|
+
family: filter[:service_name] ? nil : family,
|
70
|
+
desired_status: filter[:desired_status],
|
71
|
+
service_name: filter[:service_name],
|
72
|
+
started_by: filter[:started_by]
|
73
|
+
}.reject { |_, v| v.nil? }
|
74
|
+
|
75
|
+
all_results(:list_tasks, :task_arns, options)
|
64
76
|
end
|
65
77
|
|
66
78
|
def get_task_definition_arns(family)
|
67
79
|
all_results(:list_task_definitions, :task_definition_arns, { family_prefix: family })
|
68
80
|
end
|
69
81
|
|
70
|
-
def
|
71
|
-
task = ecs.describe_tasks(
|
82
|
+
def get_task_exit_status(cluster, task_arn, name)
|
83
|
+
task = ecs.describe_tasks(cluster: cluster, tasks: [task_arn]).tasks.first
|
72
84
|
container = task.containers.select { |c| c.name == name }.first
|
73
|
-
|
85
|
+
|
86
|
+
{
|
87
|
+
exit_code: container.exit_code,
|
88
|
+
reason: container.reason
|
89
|
+
}
|
74
90
|
end
|
75
91
|
|
76
92
|
def list_task_definition_families
|
@@ -81,10 +97,10 @@ module Broadside
|
|
81
97
|
all_results(:list_services, :service_arns, { cluster: cluster })
|
82
98
|
end
|
83
99
|
|
84
|
-
def run_task(cluster, name, command)
|
85
|
-
|
100
|
+
def run_task(cluster, name, command, options = {})
|
101
|
+
raise ArgumentError, "command: '#{command}' must be an array" unless command.is_a?(Array)
|
86
102
|
|
87
|
-
ecs.run_task(
|
103
|
+
response = ecs.run_task(
|
88
104
|
cluster: cluster,
|
89
105
|
task_definition: get_latest_task_definition_arn(name),
|
90
106
|
overrides: {
|
@@ -96,8 +112,14 @@ module Broadside
|
|
96
112
|
]
|
97
113
|
},
|
98
114
|
count: 1,
|
99
|
-
started_by: "
|
115
|
+
started_by: ((options[:started_by] ? "#{options[:started_by]}:" : '') + command.join(' '))[0...36]
|
100
116
|
)
|
117
|
+
|
118
|
+
unless response.successful? && response.tasks.try(:[], 0)
|
119
|
+
raise EcsError, "Failed to run task '#{command.join(' ')}'\n#{response.pretty_inspect}"
|
120
|
+
end
|
121
|
+
|
122
|
+
response
|
101
123
|
end
|
102
124
|
|
103
125
|
def service_exists?(cluster, family)
|
@@ -105,6 +127,28 @@ module Broadside
|
|
105
127
|
services.failures.empty? && services.services.any?
|
106
128
|
end
|
107
129
|
|
130
|
+
def check_service_and_task_definition_state!(target)
|
131
|
+
check_task_definition_state!(target)
|
132
|
+
check_service_state!(target)
|
133
|
+
end
|
134
|
+
|
135
|
+
def check_task_definition_state!(target)
|
136
|
+
unless get_latest_task_definition_arn(target.family)
|
137
|
+
raise Error, "No task definition for '#{target.family}'! Please bootstrap or manually configure one."
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def check_service_state!(target)
|
142
|
+
unless service_exists?(target.cluster, target.family)
|
143
|
+
raise Error, "No service for '#{target.family}'! Please bootstrap or manually configure one."
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def current_service_scale(target)
|
148
|
+
check_service_state!(target)
|
149
|
+
EcsManager.ecs.describe_services(cluster: target.cluster, services: [target.family]).services.first[:desired_count]
|
150
|
+
end
|
151
|
+
|
108
152
|
private
|
109
153
|
|
110
154
|
def all_results(method, key, args = {})
|
@@ -121,8 +165,8 @@ module Broadside
|
|
121
165
|
|
122
166
|
def ec2_client
|
123
167
|
@ec2_client ||= Aws::EC2::Client.new(
|
124
|
-
region: config.aws.region,
|
125
|
-
credentials: config.aws.credentials
|
168
|
+
region: Broadside.config.aws.region,
|
169
|
+
credentials: Broadside.config.aws.credentials
|
126
170
|
)
|
127
171
|
end
|
128
172
|
end
|
data/lib/broadside/error.rb
CHANGED
@@ -1,10 +1,5 @@
|
|
1
1
|
module Broadside
|
2
|
-
class
|
3
|
-
end
|
4
|
-
|
5
|
-
class Error < StandardError
|
6
|
-
def initialize(msg = 'Broadside encountered an error !')
|
7
|
-
super
|
8
|
-
end
|
9
|
-
end
|
2
|
+
class ConfigurationError < ArgumentError; end
|
3
|
+
class EcsError < StandardError; end
|
4
|
+
class Error < StandardError; end
|
10
5
|
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
def add_tag_flag(cmd)
|
2
|
+
cmd.desc 'Docker tag for application container'
|
3
|
+
cmd.arg_name 'TAG'
|
4
|
+
cmd.flag [:tag]
|
5
|
+
end
|
6
|
+
|
7
|
+
def add_target_flag(cmd)
|
8
|
+
cmd.desc 'Deployment target to use, e.g. production_web'
|
9
|
+
cmd.arg_name 'TARGET'
|
10
|
+
cmd.flag [:t, :target], type: Symbol, required: true
|
11
|
+
end
|
12
|
+
|
13
|
+
def add_instance_flag(cmd)
|
14
|
+
cmd.desc '0-based index into the array of running instances'
|
15
|
+
cmd.default_value 0
|
16
|
+
cmd.arg_name 'INSTANCE'
|
17
|
+
cmd.flag [:n, :instance], type: Fixnum
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_command_flags(cmd)
|
21
|
+
add_instance_flag(cmd)
|
22
|
+
add_target_flag(cmd)
|
23
|
+
end
|
24
|
+
|
25
|
+
desc 'Bootstrap your service and task definition from the configured definition.'
|
26
|
+
command :bootstrap do |bootstrap|
|
27
|
+
add_tag_flag(bootstrap)
|
28
|
+
add_target_flag(bootstrap)
|
29
|
+
|
30
|
+
bootstrap.action do |_, options, _|
|
31
|
+
Broadside::EcsDeploy.new(options).bootstrap
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
desc 'Gives an overview of all of the deploy targets'
|
36
|
+
command :targets do |targets|
|
37
|
+
targets.action do |_, options, _|
|
38
|
+
Broadside::Command.targets
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
desc 'Gets information about what is currently deployed.'
|
43
|
+
command :status do |status|
|
44
|
+
status.desc 'Additionally displays service and task information'
|
45
|
+
status.switch :verbose, negatable: false
|
46
|
+
|
47
|
+
add_target_flag(status)
|
48
|
+
|
49
|
+
status.action do |_, options, _|
|
50
|
+
Broadside::Command.status(options)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
desc 'Creates a single instance of the application to run a command.'
|
55
|
+
command :run do |run|
|
56
|
+
run.desc 'Broadside::Command to run (wrap argument in quotes)'
|
57
|
+
run.arg_name 'COMMAND'
|
58
|
+
run.flag [:command], type: Array
|
59
|
+
|
60
|
+
add_tag_flag(run)
|
61
|
+
add_command_flags(run)
|
62
|
+
|
63
|
+
run.action do |_, options, _|
|
64
|
+
EcsDeploy.new(options).run_commands([options[:command]], started_by: 'run')
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
desc 'Tail the logs inside a running container.'
|
69
|
+
command :logtail do |logtail|
|
70
|
+
logtail.desc 'Number of lines to tail'
|
71
|
+
logtail.default_value Broadside::Command::DEFAULT_TAIL_LINES
|
72
|
+
logtail.arg_name 'TAIL_LINES'
|
73
|
+
logtail.flag [:l, :lines], type: Fixnum
|
74
|
+
|
75
|
+
add_command_flags(logtail)
|
76
|
+
|
77
|
+
logtail.action do |_, options, _|
|
78
|
+
Broadside::Command.logtail(options)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
desc 'Establish a secure shell on an instance running the container.'
|
83
|
+
command :ssh do |ssh|
|
84
|
+
add_command_flags(ssh)
|
85
|
+
|
86
|
+
ssh.action do |_, options, _|
|
87
|
+
Broadside::Command.ssh(options)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
desc 'Establish a shell inside a running container.'
|
92
|
+
command :bash do |bash|
|
93
|
+
add_command_flags(bash)
|
94
|
+
|
95
|
+
bash.action do |_, options, _|
|
96
|
+
Broadside::Command.bash(options)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
desc 'Deploy your application.'
|
101
|
+
command :deploy do |d|
|
102
|
+
d.desc 'Deploys WITHOUT running predeploy commands'
|
103
|
+
d.command :short do |short|
|
104
|
+
add_tag_flag(short)
|
105
|
+
add_target_flag(short)
|
106
|
+
|
107
|
+
short.action do |_, options, _|
|
108
|
+
Broadside::EcsDeploy.new(options).short
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
d.desc 'Deploys WITH running predeploy commands'
|
113
|
+
d.command :full do |full|
|
114
|
+
add_tag_flag(full)
|
115
|
+
add_target_flag(full)
|
116
|
+
|
117
|
+
full.action do |_, options, _|
|
118
|
+
Broadside::EcsDeploy.new(options).full
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
d.desc 'Scales application to a given count'
|
123
|
+
d.command :scale do |scale|
|
124
|
+
scale.desc 'Specify a new scale for application'
|
125
|
+
scale.arg_name 'NUM'
|
126
|
+
scale.flag [:s, :scale], type: Fixnum
|
127
|
+
|
128
|
+
add_target_flag(scale)
|
129
|
+
|
130
|
+
scale.action do |_, options, _|
|
131
|
+
Broadside::EcsDeploy.new(options).scale(options)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
d.desc 'Rolls back n releases and deploys'
|
136
|
+
d.command :rollback do |rollback|
|
137
|
+
rollback.desc 'Number of releases to rollback'
|
138
|
+
rollback.arg_name 'COUNT'
|
139
|
+
rollback.flag [:r, :rollback], type: Fixnum
|
140
|
+
|
141
|
+
add_target_flag(rollback)
|
142
|
+
|
143
|
+
rollback.action do |_, options, _|
|
144
|
+
Broadside::EcsDeploy.new(options).rollback(options)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# GLI type coercions
|
2
|
+
accept Symbol do |val|
|
3
|
+
val.to_sym
|
4
|
+
end
|
5
|
+
accept Array do |val|
|
6
|
+
val.split(' ')
|
7
|
+
end
|
8
|
+
accept Fixnum do |val|
|
9
|
+
val.to_i
|
10
|
+
end
|
11
|
+
|
12
|
+
desc 'Configuration file to use.'
|
13
|
+
default_value 'config/broadside.conf.rb'
|
14
|
+
arg_name 'FILE'
|
15
|
+
flag [:c, :config]
|
16
|
+
|
17
|
+
desc 'Enables debug mode'
|
18
|
+
switch [:D, :debug], negatable: false
|
19
|
+
|
20
|
+
desc 'Log level output'
|
21
|
+
arg_name 'LOGLEVEL'
|
22
|
+
flag [:l, :loglevel], must_match: %w(debug info warn error fatal)
|
23
|
+
|
24
|
+
def call_hook(type, command, options, args)
|
25
|
+
hook = Broadside.config.public_send(type)
|
26
|
+
return if hook.nil?
|
27
|
+
raise "#{type} hook is not a callable proc" unless hook.is_a?(Proc)
|
28
|
+
|
29
|
+
hook_args = {
|
30
|
+
options: options,
|
31
|
+
args: args
|
32
|
+
}
|
33
|
+
|
34
|
+
if command.parent.is_a?(GLI::Command)
|
35
|
+
hook_args[:command] = command.parent.name
|
36
|
+
hook_args[:subcommand] = command.name
|
37
|
+
else
|
38
|
+
hook_args[:command] = command.name
|
39
|
+
end
|
40
|
+
|
41
|
+
debug "Calling #{type} with args '#{hook_args}'"
|
42
|
+
hook.call(hook_args)
|
43
|
+
end
|
44
|
+
|
45
|
+
pre do |global, command, options, args|
|
46
|
+
Broadside.load_config_file(global[:config])
|
47
|
+
|
48
|
+
if global[:debug]
|
49
|
+
Broadside.config.logger.level = ::Logger::DEBUG
|
50
|
+
ENV['GLI_DEBUG'] = 'true'
|
51
|
+
elsif global[:loglevel]
|
52
|
+
Broadside.config.logger.level = ::Logger.const_get(global[:loglevel].upcase)
|
53
|
+
end
|
54
|
+
|
55
|
+
call_hook(:prehook, command, options, args)
|
56
|
+
true
|
57
|
+
end
|
58
|
+
|
59
|
+
post do |global, command, options, args|
|
60
|
+
call_hook(:posthook, command, options, args)
|
61
|
+
true
|
62
|
+
end
|
63
|
+
|
64
|
+
on_error do |exception|
|
65
|
+
case exception
|
66
|
+
when Broadside::ConfigurationError
|
67
|
+
error exception.message, "Run your last command with --help for more information."
|
68
|
+
false # false skips default error handling
|
69
|
+
else
|
70
|
+
true
|
71
|
+
end
|
72
|
+
end
|
data/lib/broadside/target.rb
CHANGED
@@ -3,15 +3,14 @@ require 'pathname'
|
|
3
3
|
|
4
4
|
module Broadside
|
5
5
|
class Target
|
6
|
-
include
|
7
|
-
include
|
6
|
+
include ActiveModel::Model
|
7
|
+
include LoggingUtils
|
8
8
|
|
9
|
-
|
9
|
+
attr_reader(
|
10
10
|
:bootstrap_commands,
|
11
|
+
:cluster,
|
11
12
|
:command,
|
12
|
-
:
|
13
|
-
:env_vars,
|
14
|
-
:instance,
|
13
|
+
:docker_image,
|
15
14
|
:name,
|
16
15
|
:predeploy_commands,
|
17
16
|
:scale,
|
@@ -20,91 +19,78 @@ module Broadside
|
|
20
19
|
:task_definition_config
|
21
20
|
)
|
22
21
|
|
23
|
-
|
22
|
+
validates :cluster, :docker_image, :name, presence: true
|
23
|
+
validates :scale, numericality: { only_integer: true }
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
command: ->(target_attribute) { validate_types([Array, NilClass], target_attribute) },
|
28
|
-
env_files: ->(target_attribute) { validate_types([String, Array], target_attribute) },
|
29
|
-
predeploy_commands: ->(target_attribute) { validate_commands(target_attribute) },
|
30
|
-
scale: ->(target_attribute) { validate_types([Integer], target_attribute) },
|
31
|
-
service_config: ->(target_attribute) { validate_types([Hash, NilClass], target_attribute) },
|
32
|
-
task_definition_config: ->(target_attribute) { validate_types([Hash, NilClass], target_attribute) }
|
33
|
-
}
|
34
|
-
|
35
|
-
def initialize(name, options = {})
|
36
|
-
@name = name
|
37
|
-
@config = options
|
38
|
-
|
39
|
-
@bootstrap_commands = @config[:bootstrap_commands] || []
|
40
|
-
@cluster = @config[:cluster]
|
41
|
-
@command = @config[:command]
|
42
|
-
_env_files = @config[:env_files] || @config[:env_file]
|
43
|
-
@env_files = _env_files ? [*_env_files] : nil
|
44
|
-
@env_vars = {}
|
45
|
-
@instance = DEFAULT_INSTANCE || @config[:instance]
|
46
|
-
@predeploy_commands = @config[:predeploy_commands]
|
47
|
-
@scale = @config[:scale]
|
48
|
-
@service_config = @config[:service_config]
|
49
|
-
@tag = @config[:tag]
|
50
|
-
@task_definition_config = @config[:task_definition_config]
|
51
|
-
|
52
|
-
validate!
|
53
|
-
load_env_vars!
|
25
|
+
validates_each(:bootstrap_commands, :predeploy_commands, allow_nil: true) do |record, attr, val|
|
26
|
+
record.errors.add(attr, 'is not array of arrays') unless val.is_a?(Array) && val.all? { |v| v.is_a?(Array) }
|
54
27
|
end
|
55
28
|
|
56
|
-
|
57
|
-
|
29
|
+
validates_each(:service_config, allow_nil: true) do |record, attr, val|
|
30
|
+
record.errors.add(attr, 'is not a hash') unless val.is_a?(Hash)
|
58
31
|
end
|
59
32
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
unless invalid_messages.empty?
|
69
|
-
raise ArgumentError, invalid_messages.join("\n")
|
33
|
+
validates_each(:task_definition_config, allow_nil: true) do |record, attr, val|
|
34
|
+
if val.is_a?(Hash)
|
35
|
+
if val[:container_definitions] && val[:container_definitions].size > 1
|
36
|
+
record.errors.add(attr, 'specifies > 1 container definition but this is not supported yet')
|
37
|
+
end
|
38
|
+
else
|
39
|
+
record.errors.add(attr, 'is not a hash')
|
70
40
|
end
|
71
41
|
end
|
72
42
|
|
73
|
-
|
74
|
-
|
75
|
-
|
43
|
+
validates_each(:command, allow_nil: true) do |record, attr, val|
|
44
|
+
record.errors.add(attr, 'is not an array of strings') unless val.is_a?(Array) && val.all? { |v| v.is_a?(String) }
|
45
|
+
end
|
76
46
|
|
77
|
-
|
78
|
-
|
79
|
-
env_file = env_file.expand_path(dir)
|
80
|
-
end
|
47
|
+
def initialize(name, options = {})
|
48
|
+
@name = name
|
81
49
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
50
|
+
config = options.deep_dup
|
51
|
+
@bootstrap_commands = config.delete(:bootstrap_commands)
|
52
|
+
@cluster = config.delete(:cluster) || Broadside.config.aws.ecs_default_cluster
|
53
|
+
@command = config.delete(:command)
|
54
|
+
@docker_image = config.delete(:docker_image) || Broadside.config.default_docker_image
|
55
|
+
@predeploy_commands = config.delete(:predeploy_commands)
|
56
|
+
@scale = config.delete(:scale)
|
57
|
+
@service_config = config.delete(:service_config)
|
58
|
+
@task_definition_config = config.delete(:task_definition_config)
|
59
|
+
|
60
|
+
@env_files = Array.wrap(config.delete(:env_files) || config.delete(:env_file)).map do |env_path|
|
61
|
+
env_file = Pathname.new(env_path)
|
62
|
+
next env_file if env_file.absolute?
|
63
|
+
|
64
|
+
dir = Broadside.config.config_file ? Pathname.new(Broadside.config.config_file).dirname : Dir.pwd
|
65
|
+
env_file.expand_path(dir)
|
88
66
|
end
|
89
67
|
|
90
|
-
|
91
|
-
|
68
|
+
raise ConfigurationError, errors.full_messages unless valid?
|
69
|
+
warn "Target #{@name} was configured with invalid/unused options: #{config}" unless config.empty?
|
92
70
|
end
|
93
71
|
|
94
|
-
def
|
95
|
-
|
72
|
+
def ecs_env_vars
|
73
|
+
@env_vars ||= @env_files.inject({}) do |env_variables, env_file|
|
74
|
+
raise ConfigurationError, "Specified env_file: '#{env_file}' does not exist!" unless env_file.exist?
|
96
75
|
|
97
|
-
|
76
|
+
begin
|
77
|
+
env_variables.merge(Dotenv.load(env_file))
|
78
|
+
rescue Dotenv::FormatError => e
|
79
|
+
raise e.class, "Error parsing #{env_file}: #{e.message}", e.backtrace
|
80
|
+
end
|
81
|
+
end.map { |k, v| { 'name' => k, 'value' => v } }
|
98
82
|
end
|
99
83
|
|
100
|
-
def
|
101
|
-
|
102
|
-
|
84
|
+
def family
|
85
|
+
"#{Broadside.config.application}_#{@name}"
|
86
|
+
end
|
103
87
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
88
|
+
def to_h
|
89
|
+
{
|
90
|
+
Target: @name,
|
91
|
+
Image: "#{@docker_image}:#{@tag || 'no_tag_configured'}",
|
92
|
+
Cluster: @cluster
|
93
|
+
}
|
108
94
|
end
|
109
95
|
end
|
110
96
|
end
|