decking 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +16 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +89 -0
- data/Guardfile +14 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +9 -0
- data/bin/decking +109 -0
- data/bin/decking-test +47 -0
- data/decking.gemspec +37 -0
- data/doc/notes.md +5 -0
- data/lib/decking/container/attach.rb +22 -0
- data/lib/decking/container/create.rb +64 -0
- data/lib/decking/container/delete.rb +21 -0
- data/lib/decking/container/inspect.rb +0 -0
- data/lib/decking/container/restart.rb +0 -0
- data/lib/decking/container/start.rb +40 -0
- data/lib/decking/container/stop.rb +25 -0
- data/lib/decking/container/top.rb +0 -0
- data/lib/decking/container/wait.rb +0 -0
- data/lib/decking/containers.rb +71 -0
- data/lib/decking/helpers.rb +105 -0
- data/lib/decking/image/build.rb +0 -0
- data/lib/decking/image/tag.rb +0 -0
- data/lib/decking/images.rb +48 -0
- data/lib/decking/parser.rb +166 -0
- data/lib/decking/version.rb +3 -0
- data/lib/decking.rb +25 -0
- data/spec/parser_spec.rb +60 -0
- data/spec/resources/decking-container-tests.yaml +62 -0
- data/spec/resources/decking.yaml +109 -0
- data/spec/spec_helper.rb +2 -0
- data/vendor/bundle/.gitignore +0 -0
- metadata +281 -0
@@ -0,0 +1,105 @@
|
|
1
|
+
module Decking
|
2
|
+
module Helpers
|
3
|
+
extend self
|
4
|
+
|
5
|
+
CONSOLE_LENGTH=80
|
6
|
+
|
7
|
+
def run_with_progress(title, &block)
|
8
|
+
command = Thread.new(&block).tap{ |t| t.abort_on_exception = true}
|
9
|
+
|
10
|
+
progress = Thread.new do
|
11
|
+
opts = { title: title,
|
12
|
+
total: nil,
|
13
|
+
length: CONSOLE_LENGTH,
|
14
|
+
format: '%t%B',
|
15
|
+
progress_mark: ' ',
|
16
|
+
unknown_progress_animation_steps: ['.. .', '... ', ' ... ', ' ...', '. ..'] }
|
17
|
+
progressbar = ProgressBar.create opts
|
18
|
+
|
19
|
+
begin
|
20
|
+
loop do
|
21
|
+
progressbar.increment
|
22
|
+
sleep 0.5
|
23
|
+
end
|
24
|
+
rescue RuntimeError => e
|
25
|
+
if e.message == 'Shutdown'
|
26
|
+
progressbar.total = 100
|
27
|
+
progressbar.format '%t ' + "\u2713".green
|
28
|
+
progressbar.finish
|
29
|
+
else
|
30
|
+
raise RuntimeError e
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end.tap {|t| t.abort_on_exception = true }
|
34
|
+
|
35
|
+
command.join
|
36
|
+
progress.raise 'Shutdown'
|
37
|
+
progress.join
|
38
|
+
finished = true
|
39
|
+
rescue Interrupt
|
40
|
+
clear_progressline
|
41
|
+
puts "I know you did't mean to do that... try again if you really do".yellow
|
42
|
+
rescue Exception => e
|
43
|
+
clear_progressline
|
44
|
+
puts e.class
|
45
|
+
puts e.message
|
46
|
+
puts e.backtrace.inspect
|
47
|
+
exit
|
48
|
+
ensure
|
49
|
+
begin
|
50
|
+
unless finished
|
51
|
+
command.join
|
52
|
+
progress.raise 'Shutdown'
|
53
|
+
progress.join
|
54
|
+
end
|
55
|
+
rescue Interrupt
|
56
|
+
puts "Caught second interrupt, exiting...".red
|
57
|
+
exit
|
58
|
+
rescue SystemExit
|
59
|
+
puts "Caught SystemExit. Exiting...".red
|
60
|
+
exit
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def run_with_threads_multiplexed method, containers, *args
|
65
|
+
clear_progressline
|
66
|
+
threads = Array.new
|
67
|
+
containers.map do |name, container|
|
68
|
+
threads << Thread.new do
|
69
|
+
container.method(method).call(*args)
|
70
|
+
sleep 0.1
|
71
|
+
end
|
72
|
+
end
|
73
|
+
threads.map { |thread| thread.join }
|
74
|
+
rescue Interrupt
|
75
|
+
threads.map { |thread| thread.kill }
|
76
|
+
end
|
77
|
+
|
78
|
+
def clear_progressline
|
79
|
+
$stdout.print " " * CONSOLE_LENGTH + "\r"
|
80
|
+
#$stdout.print "\n"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
class String
|
86
|
+
def black; "\033[30m#{self}\033[0m"; end
|
87
|
+
def red; "\033[31m#{self}\033[0m"; end
|
88
|
+
def green; "\033[32m#{self}\033[0m"; end
|
89
|
+
def yellow; "\033[33m#{self}\033[0m"; end
|
90
|
+
def brown; "\033[33m#{self}\033[0m"; end
|
91
|
+
def blue; "\033[34m#{self}\033[0m"; end
|
92
|
+
def magenta; "\033[35m#{self}\033[0m"; end
|
93
|
+
def cyan; "\033[36m#{self}\033[0m"; end
|
94
|
+
def gray; "\033[37m#{self}\033[0m"; end
|
95
|
+
def bg_black; "\033[40m#{self}\033[0m"; end
|
96
|
+
def bg_red; "\033[41m#{self}\033[0m"; end
|
97
|
+
def bg_green; "\033[42m#{self}\033[0m"; end
|
98
|
+
def bg_brown; "\033[43m#{self}\033[0m"; end
|
99
|
+
def bg_blue; "\033[44m#{self}\033[0m"; end
|
100
|
+
def bg_magenta; "\033[45m#{self}\033[0m"; end
|
101
|
+
def bg_cyan; "\033[46m#{self}\033[0m"; end
|
102
|
+
def bg_gray; "\033[47m#{self}\033[0m"; end
|
103
|
+
def bold; "\033[1m#{self}\033[22m"; end
|
104
|
+
def reverse_color; "\033[7m#{self}\033[27m"; end
|
105
|
+
end
|
File without changes
|
File without changes
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Decking
|
2
|
+
class Image
|
3
|
+
include Decking::Helpers
|
4
|
+
class << self
|
5
|
+
include Decking::Helpers
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
#def delete_all ; map{|n, c| c.delete }; end
|
9
|
+
#def delete_all!; map{|n, c| c.delete! }; end
|
10
|
+
|
11
|
+
def images
|
12
|
+
@images ||= Hash.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def instances
|
16
|
+
@instances ||= Hash.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def add params
|
20
|
+
images.update params.name => params
|
21
|
+
self[params.name]
|
22
|
+
end
|
23
|
+
|
24
|
+
def [](name)
|
25
|
+
instances[name] ||= new(name, @images[name])
|
26
|
+
end
|
27
|
+
|
28
|
+
def each &block
|
29
|
+
@instances.each(&block)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
attr_reader :name, :config
|
34
|
+
|
35
|
+
def initialize name, params
|
36
|
+
@name = name
|
37
|
+
@config = params
|
38
|
+
end
|
39
|
+
|
40
|
+
def method_missing method, *args, &block
|
41
|
+
if config.key? method
|
42
|
+
config[method]
|
43
|
+
else
|
44
|
+
super
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
module Decking
|
2
|
+
module Parser
|
3
|
+
# Singleton Method: https://practicingruby.com/articles/ruby-and-the-singleton-pattern-dont-get-along
|
4
|
+
extend self
|
5
|
+
|
6
|
+
attr_accessor :config, :config_path
|
7
|
+
|
8
|
+
def config_file config_file
|
9
|
+
config_file ||= 'decking.yaml'
|
10
|
+
|
11
|
+
@config = Hashie::Mash.new(YAML.load_file(config_file))
|
12
|
+
@config_path = File.realpath(config_file)
|
13
|
+
|
14
|
+
confirm_requirements
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
def print
|
19
|
+
puts config.to_yaml
|
20
|
+
end
|
21
|
+
|
22
|
+
def parse cluster
|
23
|
+
parse_images
|
24
|
+
parse_containers
|
25
|
+
parse_clusters
|
26
|
+
parse_groups
|
27
|
+
merge_cluster_config cluster
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def confirm_requirements
|
33
|
+
raise "No Containers Defined" unless config.containers?
|
34
|
+
raise "No Clusters Defined" unless config.clusters?
|
35
|
+
raise "No Images Defined" unless config.images?
|
36
|
+
end
|
37
|
+
|
38
|
+
def parse_images
|
39
|
+
config.images.each do |key, val|
|
40
|
+
if val.nil?
|
41
|
+
config.images[key] = Hashie::Mash.new
|
42
|
+
config.images[key].name = "#{key}:latest"
|
43
|
+
elsif val.is_a?(String)
|
44
|
+
config.images[key] = Hashie::Mash.new
|
45
|
+
config.images[key].name = val
|
46
|
+
end
|
47
|
+
config.images[key].tag ||= "latest"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def parse_containers
|
52
|
+
config.containers.each do |key, val|
|
53
|
+
config.containers[key] ||= Hashie::Mash.new
|
54
|
+
config.containers[key].links ||= Array.new
|
55
|
+
config.containers[key].binds ||= Array.new
|
56
|
+
config.containers[key].lxc_conf ||= Array.new
|
57
|
+
config.containers[key].domainname ||= ""
|
58
|
+
config.containers[key].command ||= ""
|
59
|
+
config.containers[key].entrypoint ||= nil
|
60
|
+
config.containers[key].memory ||= 0
|
61
|
+
config.containers[key].memory_swap ||= 0
|
62
|
+
config.containers[key].cpu_shares ||= 0
|
63
|
+
config.containers[key].cpu_set ||= ""
|
64
|
+
config.containers[key].attach_stdout ||= false
|
65
|
+
config.containers[key].attach_stderr ||= false
|
66
|
+
config.containers[key].attach_stdin ||= false
|
67
|
+
config.containers[key].tty ||= false
|
68
|
+
config.containers[key].open_stdin ||= false
|
69
|
+
config.containers[key].stdin_once ||= false
|
70
|
+
config.containers[key].volumes_from ||= Array.new
|
71
|
+
config.containers[key].image ||= key
|
72
|
+
config.containers[key].port ||= Array.new
|
73
|
+
config.containers[key].aliases ||= Array.new
|
74
|
+
config.containers[key].data ||= false
|
75
|
+
config.containers[key].hostname ||= key
|
76
|
+
config.containers[key].links.each_with_index do |v, idx|
|
77
|
+
config.containers[key].links[idx] = resolve_dependency v unless v.instance_of? Hash
|
78
|
+
end
|
79
|
+
config.containers[key].volumes_from.each_with_index do |v, idx|
|
80
|
+
unless config.containers.key? v
|
81
|
+
raise "'volumes_from' dependency '" + v + "' of container '" + key + "' does not exist"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def parse_clusters
|
88
|
+
config.clusters.each do |key, val|
|
89
|
+
if config.clusters[key].instance_of? Array
|
90
|
+
cont_ar = config.clusters[key]
|
91
|
+
config.clusters[key] = Hashie::Mash.new
|
92
|
+
config.clusters[key].containers = cont_ar
|
93
|
+
end
|
94
|
+
if (config.clusters[key].key? 'group') && (!config.groups.key?(config.clusters[key].group))
|
95
|
+
raise "Cluster '" + key + "' references invalid group '" + config.clusters[key].group
|
96
|
+
end
|
97
|
+
if (!config.clusters[key].key? 'group') && (config.groups.key? key)
|
98
|
+
config.clusters[key].group = key
|
99
|
+
end
|
100
|
+
|
101
|
+
raise "Cluster '" + key + "' is empty" unless config.clusters[key].key? "containers"
|
102
|
+
raise "Cluster '" + key + "' containers should be an Array" unless config.clusters[key].containers.instance_of? Array
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def parse_groups
|
107
|
+
config.groups.each do |key, val|
|
108
|
+
config.groups[key] = Hashie::Mash.new if config.groups[key].nil?
|
109
|
+
config.groups[key].options = Hashie::Mash.new unless config.groups[key].key? 'options'
|
110
|
+
config.groups[key].containers = Hashie::Mash.new unless config.groups[key].key? 'containers'
|
111
|
+
config.groups[key].containers.each do |c_key, c_val|
|
112
|
+
if config.groups[key].containers[c_key].key? 'links'
|
113
|
+
config.groups[key].containers[c_key].links.each_with_index do |v, idx|
|
114
|
+
config.groups[key].containers[c_key].links[idx] = resolve_dependency v
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def merge_cluster_config cluster
|
122
|
+
raise "Cluster '" + cluster + "' doesn't exist" unless config.clusters.key? cluster
|
123
|
+
c = Hashie::Mash.new
|
124
|
+
c.containers = Hash.new
|
125
|
+
|
126
|
+
# Merge primary container configs
|
127
|
+
config.clusters[cluster].containers.each_with_index do |key, idx|
|
128
|
+
c.containers[key] = config.containers[key]
|
129
|
+
end
|
130
|
+
|
131
|
+
c.containers.each do |k, v|
|
132
|
+
# Merge Global Overrides
|
133
|
+
c.containers[k] = c.containers[k].deep_merge(config.global) if config.key? 'global'
|
134
|
+
# Merge Group Overrides
|
135
|
+
c.containers[k] = c.containers[k].deep_merge(config.groups[config.clusters[cluster].group].options)
|
136
|
+
# Merge Group Container Overrides
|
137
|
+
if config.groups[config.clusters[cluster].group].containers.key? k
|
138
|
+
c.containers[k] = c.containers[k].deep_merge(config.groups[config.clusters[cluster].group].containers[k])
|
139
|
+
end
|
140
|
+
c.containers[k].name = k + '.' + cluster
|
141
|
+
c.containers[k].env.CONTAINER_NAME = k + '.' + cluster
|
142
|
+
c.containers[k].domainname = cluster + '.' + config.global.domainname if config.key?('global') && config.global.key?('domainname')
|
143
|
+
end
|
144
|
+
images = self.config.images
|
145
|
+
group = self.config.clusters[cluster].group
|
146
|
+
self.config = c
|
147
|
+
self.config.images = images
|
148
|
+
self.config.cluster = cluster
|
149
|
+
self.config.group = group
|
150
|
+
self.config
|
151
|
+
end
|
152
|
+
|
153
|
+
def resolve_dependency dep
|
154
|
+
ret = Hash.new
|
155
|
+
spl = dep.split ':'
|
156
|
+
ret["dep"] = spl[0]
|
157
|
+
unless spl[1].nil?
|
158
|
+
ret["alias"] = spl[1]
|
159
|
+
else
|
160
|
+
ret["alias"] = spl[0]
|
161
|
+
end
|
162
|
+
ret
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
end
|
data/lib/decking.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'hashie'
|
2
|
+
require 'docker'
|
3
|
+
Docker.validate_version!
|
4
|
+
require "ruby-progressbar"
|
5
|
+
require 'thread'
|
6
|
+
require 'yaml'
|
7
|
+
|
8
|
+
require 'log4r'
|
9
|
+
require 'log4r/formatter/patternformatter'
|
10
|
+
require 'log4r/outputter/syslogoutputter'
|
11
|
+
require 'syslog'
|
12
|
+
include Syslog::Constants
|
13
|
+
|
14
|
+
Log4r::Logger.global.level = Log4r::ALL
|
15
|
+
Log4r::StdoutOutputter.new('stdout', formatter: Log4r::PatternFormatter.new( pattern: '%d (%C) %l: %m', date_pattern: '%FT%T%:z' ))
|
16
|
+
Log4r::SyslogOutputter.new('decking', logopt: LOG_CONS | LOG_PID , facility: LOG_USER, formatter: Log4r::PatternFormatter.new( date_method: 'usec', pattern: '(%C} %l: %m'))
|
17
|
+
Log4r::Logger.new('decking')
|
18
|
+
Log4r::Logger['decking'].add('decking')
|
19
|
+
Log4r::Logger['decking'].add('stdout')
|
20
|
+
Log4r::Logger['decking'].debug "Initialized #{__FILE__}"
|
21
|
+
|
22
|
+
require_relative "decking/version"
|
23
|
+
require_relative "decking/helpers"
|
24
|
+
require_relative "decking/parser"
|
25
|
+
require_relative "decking/containers"
|
data/spec/parser_spec.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe Decking::Parser do
|
4
|
+
before(:each) { Decking::Parser.config_file('spec/resources/decking.yaml') }
|
5
|
+
|
6
|
+
describe '#parse' do
|
7
|
+
|
8
|
+
it 'sets image value to key when blank' do
|
9
|
+
Decking::Parser.parse 'qa'
|
10
|
+
expect(Decking::Parser.config.images.blank.name).to eq("blank:latest")
|
11
|
+
expect(Decking::Parser.config.images.base.name).to eq("fail")
|
12
|
+
expect(Decking::Parser.config.images.repos.name).to eq("repos:v1.02")
|
13
|
+
expect(Decking::Parser.config.images["eds-webapp"].name).to eq("eds-webapp:latest")
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'sets image key in containers to container name when missing' do
|
17
|
+
Decking::Parser.parse 'qa'
|
18
|
+
expect(Decking::Parser.config.containers.blank_container_image.image).to eq("blank_container_image")
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'resolves links into container and alias' do
|
22
|
+
Decking::Parser.parse 'qa'
|
23
|
+
expect(Decking::Parser.config.containers.repos.links[0]).to eq({"dep" => "elasticsearch", "alias" => "es"})
|
24
|
+
expect(Decking::Parser.config.containers.repos.links[1]).to eq({"dep" => "config", "alias" => "config"})
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'ensures that volumes_from links exist' do
|
28
|
+
Decking::Parser.config.containers.repos.volumes_from = ["not-exists"]
|
29
|
+
expect{Decking::Parser.parse 'qa'}.to raise_error(RuntimeError)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'raises an error when a cluster group does not exist' do
|
33
|
+
Decking::Parser.config.clusters.no_group = Hashie::Mash.new
|
34
|
+
Decking::Parser.config.clusters.no_group.group = "no_group"
|
35
|
+
expect{Decking::Parser.parse 'qa'}.to raise_error(RuntimeError)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'resolves links into container and alias' do
|
39
|
+
Decking::Parser.parse 'qa-mod'
|
40
|
+
expect(Decking::Parser.config.containers["webapp-admin"].links[0]).to eq({"dep" => "elasticsearch", "alias" => "elasticsearch"})
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'appropriately handles overrides' do
|
44
|
+
Decking::Parser.parse 'qa'
|
45
|
+
expect(Decking::Parser.config.containers.keys).to eq(['blank_container_image', 'repos', 'config', 'webapp-main', 'webapp-admin'])
|
46
|
+
expect(Decking::Parser.config.containers['webapp-admin'].env.WEBAPP).to eq('admin')
|
47
|
+
expect(Decking::Parser.config.containers['webapp-admin'].env.ENVIRONMENT).to eq('qa')
|
48
|
+
expect(Decking::Parser.config.containers['webapp-admin'].env.TEST_VAR).to eq('test')
|
49
|
+
expect(Decking::Parser.config.containers['webapp-admin'].env.GITHUB_REPO).to eq('test')
|
50
|
+
expect(Decking::Parser.config.containers['webapp-admin'].env.AWS_ACCESS_KEY).to eq('key')
|
51
|
+
expect(Decking::Parser.config.containers['webapp-admin'].env.AWS_SECRET_ACCESS_KEY).to eq('secret2')
|
52
|
+
expect(Decking::Parser.config.containers['webapp-admin'].image).to eq('webapp')
|
53
|
+
expect(Decking::Parser.config.containers['webapp-admin'].volumes_from).to eq(['repos','config'])
|
54
|
+
expect(Decking::Parser.config.containers['webapp-admin'].port).to eq(['82:80'])
|
55
|
+
expect(Decking::Parser.config.group).to eq('qa')
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# vim: set foldmethod=indent
|
2
|
+
---
|
3
|
+
|
4
|
+
images:
|
5
|
+
ubuntu:
|
6
|
+
eds-webapp:
|
7
|
+
name: test
|
8
|
+
|
9
|
+
containers:
|
10
|
+
ubuntu-hello-world:
|
11
|
+
image: ubuntu
|
12
|
+
port:
|
13
|
+
- 82:80
|
14
|
+
command: /bin/sh -c "while true; do echo Hello world; sleep 0.5; done"
|
15
|
+
ubuntu-hello-frank:
|
16
|
+
image: ubuntu
|
17
|
+
command: /bin/sh -c "while true; do echo Hello frank; sleep 0.5; done"
|
18
|
+
ubuntu-hello-josh:
|
19
|
+
image: ubuntu
|
20
|
+
command: /bin/sh -c "while true; do echo Hello josh; sleep 0.5; done"
|
21
|
+
ubuntu-hello-stderr:
|
22
|
+
image: ubuntu
|
23
|
+
command: /bin/sh -c "while true; do echo error will robinson >&2; sleep 0.5; done"
|
24
|
+
hello-chris:
|
25
|
+
image: ubuntu
|
26
|
+
command: /bin/sh -c "while true; do echo 'Hello Chris!!'; sleep 0.5; done"
|
27
|
+
hello-brandon:
|
28
|
+
image: ubuntu
|
29
|
+
command: /bin/sh -c "while true; do echo 'Hello Brandon!!'; sleep 0.5; done"
|
30
|
+
|
31
|
+
clusters:
|
32
|
+
container-tests:
|
33
|
+
- hello-chris
|
34
|
+
- hello-brandon
|
35
|
+
- ubuntu-hello-stderr
|
36
|
+
|
37
|
+
groups:
|
38
|
+
container-tests:
|
39
|
+
options:
|
40
|
+
env:
|
41
|
+
OPTIONS_ENV: false
|
42
|
+
OPTIONS_ENV_OVERRIDE: 'this will not be the value'
|
43
|
+
GLOBAL_OVERRIDE_AWS_REGION: 'us-east-1'
|
44
|
+
containers:
|
45
|
+
hello-brandon:
|
46
|
+
env:
|
47
|
+
OPTIONS_ENV_OVERRIDE: 'this is the real value'
|
48
|
+
ubuntu:
|
49
|
+
port:
|
50
|
+
- 83:81
|
51
|
+
- 82:80
|
52
|
+
env:
|
53
|
+
CONTAINERS_OPTS_ENV: false
|
54
|
+
OPTIONS_ENV_OVERRIDE: 'this is the real value'
|
55
|
+
|
56
|
+
|
57
|
+
global:
|
58
|
+
env:
|
59
|
+
AWS_ACCESS_KEY: key
|
60
|
+
AWS_SECRET_ACCESS_KEY: secret
|
61
|
+
GLOBAL_OVERRIDE_AWS_REGION: 'us-midwest-7'
|
62
|
+
domainname: qa.randywallace.com
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# vim: set foldmethod=indent
|
2
|
+
---
|
3
|
+
|
4
|
+
images:
|
5
|
+
base: fail
|
6
|
+
config:
|
7
|
+
repos:
|
8
|
+
name: repos:v1.02
|
9
|
+
eds-webapp:
|
10
|
+
elasticsearch:
|
11
|
+
tag: 1.5.0
|
12
|
+
blank:
|
13
|
+
|
14
|
+
containers:
|
15
|
+
ubuntu:
|
16
|
+
port:
|
17
|
+
- 82:80
|
18
|
+
command: "/bin/sh -c 'while true; do echo Hello world; sleep 1; done'"
|
19
|
+
blank_container_image:
|
20
|
+
repos:
|
21
|
+
image: repos
|
22
|
+
data: true
|
23
|
+
links:
|
24
|
+
- elasticsearch:es
|
25
|
+
- config
|
26
|
+
config:
|
27
|
+
image: config
|
28
|
+
data: true
|
29
|
+
elasticsearch:
|
30
|
+
image: elasticsearch
|
31
|
+
port:
|
32
|
+
- 9200:9200
|
33
|
+
volumes_from:
|
34
|
+
- repos
|
35
|
+
webapp-main:
|
36
|
+
image: webapp
|
37
|
+
volumes_from:
|
38
|
+
- repos
|
39
|
+
- config
|
40
|
+
port:
|
41
|
+
- 80:80
|
42
|
+
extra: webapp-main
|
43
|
+
webapp-admin:
|
44
|
+
image: webapp
|
45
|
+
volumes_from:
|
46
|
+
- repos
|
47
|
+
- config
|
48
|
+
port:
|
49
|
+
- 81:80
|
50
|
+
extra: webapp-admin
|
51
|
+
|
52
|
+
clusters:
|
53
|
+
qa:
|
54
|
+
- blank_container_image
|
55
|
+
- repos
|
56
|
+
- config
|
57
|
+
- webapp-main
|
58
|
+
- webapp-admin
|
59
|
+
qa-mod:
|
60
|
+
- repos
|
61
|
+
- config
|
62
|
+
- elasticsearch
|
63
|
+
- webapp-admin
|
64
|
+
container-tests:
|
65
|
+
- ubuntu
|
66
|
+
|
67
|
+
groups:
|
68
|
+
qa:
|
69
|
+
options:
|
70
|
+
env:
|
71
|
+
ENVIRONMENT: qa
|
72
|
+
TAG: v1.0.0
|
73
|
+
GITHUB_ACCOUNT: randywallace
|
74
|
+
GITHUB_REPO: test
|
75
|
+
GITHUB_BRANCH: master
|
76
|
+
GITHUB_TOKEN: token
|
77
|
+
TEST_VAR: test
|
78
|
+
containers:
|
79
|
+
webapp-admin:
|
80
|
+
env:
|
81
|
+
WEBAPP: admin
|
82
|
+
AWS_SECRET_ACCESS_KEY: secret2
|
83
|
+
port:
|
84
|
+
- 82:80
|
85
|
+
qa-mod:
|
86
|
+
options:
|
87
|
+
env:
|
88
|
+
ENVIRONMENT: qa-admin
|
89
|
+
TAG: v1.0.0
|
90
|
+
WEBAPP: original
|
91
|
+
containers:
|
92
|
+
webapp-admin:
|
93
|
+
port:
|
94
|
+
- 82:80
|
95
|
+
links:
|
96
|
+
- "elasticsearch:elasticsearch"
|
97
|
+
env:
|
98
|
+
WEBAPP: replace
|
99
|
+
container-tests:
|
100
|
+
options:
|
101
|
+
env:
|
102
|
+
ENVIRONMENT: qa-admin
|
103
|
+
TAG: v1.0.0
|
104
|
+
|
105
|
+
global:
|
106
|
+
env:
|
107
|
+
AWS_ACCESS_KEY: key
|
108
|
+
AWS_SECRET_ACCESS_KEY: secret
|
109
|
+
domainname: qa.randywallace.com
|
data/spec/spec_helper.rb
ADDED
File without changes
|