decking 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|