percheron 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +3 -3
- data/Guardfile +5 -0
- data/bin/percheron +8 -4
- data/lib/percheron.rb +3 -0
- data/lib/percheron/actions.rb +15 -0
- data/lib/percheron/actions/base.rb +50 -0
- data/lib/percheron/actions/build.rb +47 -0
- data/lib/percheron/actions/create.rb +109 -0
- data/lib/percheron/actions/exec.rb +51 -0
- data/lib/percheron/actions/purge.rb +38 -0
- data/lib/percheron/actions/recreate.rb +98 -0
- data/lib/percheron/actions/rename.rb +64 -0
- data/lib/percheron/actions/restart.rb +31 -0
- data/lib/percheron/actions/start.rb +46 -0
- data/lib/percheron/actions/stop.rb +27 -0
- data/lib/percheron/cli.rb +1 -0
- data/lib/percheron/cli/abstract_command.rb +7 -0
- data/lib/percheron/cli/create_command.rb +3 -2
- data/lib/percheron/cli/list_command.rb +2 -8
- data/lib/percheron/cli/main_command.rb +1 -0
- data/lib/percheron/cli/purge_command.rb +12 -0
- data/lib/percheron/cli/recreate_command.rb +9 -2
- data/lib/percheron/cli/restart_command.rb +3 -2
- data/lib/percheron/cli/start_command.rb +3 -2
- data/lib/percheron/cli/stop_command.rb +3 -2
- data/lib/percheron/container.rb +120 -5
- data/lib/percheron/errors.rb +0 -1
- data/lib/percheron/formatters/stack/table.rb +1 -1
- data/lib/percheron/null_container.rb +13 -0
- data/lib/percheron/oh_dear.rb +46 -0
- data/lib/percheron/stack.rb +90 -31
- data/lib/percheron/validators/container.rb +9 -1
- data/lib/percheron/version.rb +1 -1
- data/percheron.gemspec +2 -0
- metadata +45 -11
- data/lib/percheron/container/actions.rb +0 -15
- data/lib/percheron/container/actions/base.rb +0 -21
- data/lib/percheron/container/actions/build.rb +0 -58
- data/lib/percheron/container/actions/create.rb +0 -56
- data/lib/percheron/container/actions/recreate.rb +0 -110
- data/lib/percheron/container/actions/start.rb +0 -58
- data/lib/percheron/container/actions/stop.rb +0 -33
- data/lib/percheron/container/main.rb +0 -193
- data/lib/percheron/container/null.rb +0 -15
data/lib/percheron/errors.rb
CHANGED
@@ -0,0 +1,46 @@
|
|
1
|
+
module Percheron
|
2
|
+
class OhDear
|
3
|
+
|
4
|
+
def initialize(exception)
|
5
|
+
@exception = exception
|
6
|
+
end
|
7
|
+
|
8
|
+
def generate
|
9
|
+
<<-EOS
|
10
|
+
|
11
|
+
OH DEAR, we are terribly sorry.. something unexpected occurred :(
|
12
|
+
|
13
|
+
--snip--
|
14
|
+
|
15
|
+
Info
|
16
|
+
----
|
17
|
+
Ruby: #{RUBY_VERSION}
|
18
|
+
Percheron: #{Percheron::VERSION}
|
19
|
+
|
20
|
+
Trace
|
21
|
+
-----
|
22
|
+
#{exception_message}
|
23
|
+
|
24
|
+
#{exception_backtrace}
|
25
|
+
|
26
|
+
--snip--
|
27
|
+
|
28
|
+
Please copy the detail between the --snip--'s above and raise a ticket - https://github.com/ashmckenzie/percheron/issues/new?labels=bug
|
29
|
+
|
30
|
+
EOS
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
attr_reader :exception
|
36
|
+
|
37
|
+
def exception_message
|
38
|
+
exception.inspect
|
39
|
+
end
|
40
|
+
|
41
|
+
def exception_backtrace
|
42
|
+
exception.backtrace ? exception.backtrace.join("\n") : ''
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
data/lib/percheron/stack.rb
CHANGED
@@ -12,20 +12,17 @@ module Percheron
|
|
12
12
|
self
|
13
13
|
end
|
14
14
|
|
15
|
-
def self.
|
16
|
-
|
17
|
-
config.stacks.each do |stack_name, _|
|
15
|
+
def self.get(config, stack_name=nil)
|
16
|
+
if stack_name
|
18
17
|
stack = new(config, stack_name)
|
19
|
-
|
20
|
-
end
|
21
|
-
all
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.get(config, stack_name)
|
25
|
-
if stack = all(config)[stack_name]
|
26
|
-
{ stack.name => stack }
|
18
|
+
stack ? { stack.name => stack } : {}
|
27
19
|
else
|
28
|
-
{}
|
20
|
+
all = {}
|
21
|
+
config.stacks.each do |stack_name, _|
|
22
|
+
stack = new(config, stack_name)
|
23
|
+
all[stack.name] = stack
|
24
|
+
end
|
25
|
+
all
|
29
26
|
end
|
30
27
|
end
|
31
28
|
|
@@ -33,33 +30,52 @@ module Percheron
|
|
33
30
|
stack_config.containers.to_hash_by_key(:name)
|
34
31
|
end
|
35
32
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
33
|
+
# FIXME: YUCK
|
34
|
+
def filter_containers(container_names=[])
|
35
|
+
container_names = !container_names.empty? ? container_names : filter_container_names
|
36
|
+
container_names.inject({}) do |all, container_name|
|
37
|
+
all[container_name] = Container.new(config, self, container_name)
|
38
|
+
all
|
41
39
|
end
|
42
|
-
containers
|
43
40
|
end
|
44
41
|
|
45
|
-
def stop!
|
46
|
-
|
42
|
+
def stop!(container_names: [])
|
43
|
+
container_names = dependant_containers(container_names).reverse
|
44
|
+
serial_processor(container_names) { |container| Actions::Stop.new(container).execute! }
|
47
45
|
end
|
48
46
|
|
49
|
-
def start!
|
50
|
-
|
47
|
+
def start!(container_names: [])
|
48
|
+
container_names = dependant_containers(container_names)
|
49
|
+
serial_processor(container_names) { |container| Actions::Start.new(container, container.dependant_containers.values).execute! }
|
51
50
|
end
|
52
51
|
|
53
|
-
def restart!
|
54
|
-
|
52
|
+
def restart!(container_names: [])
|
53
|
+
container_names = dependant_containers(container_names).reverse
|
54
|
+
serial_processor(container_names) { |container| Actions::Restart.new(container).execute! }
|
55
55
|
end
|
56
56
|
|
57
|
-
def create!
|
58
|
-
|
57
|
+
def create!(container_names: [])
|
58
|
+
container_names = dependant_containers(container_names)
|
59
|
+
serial_processor(container_names) { |container| Actions::Create.new(container).execute! }
|
59
60
|
end
|
60
61
|
|
61
|
-
def recreate!(force_recreate: false,
|
62
|
-
|
62
|
+
def recreate!(container_names: [], force_recreate: false, delete: false)
|
63
|
+
current = container_names_final = filter_container_names(container_names)
|
64
|
+
|
65
|
+
# FIXME: make this suck less
|
66
|
+
while true
|
67
|
+
current = deps = containers_affected(current).uniq
|
68
|
+
break if deps.empty?
|
69
|
+
container_names_final += deps
|
70
|
+
end
|
71
|
+
|
72
|
+
serial_processor(container_names_final.uniq) do |container|
|
73
|
+
Actions::Recreate.new(container, force_recreate: force_recreate, delete: delete).execute!
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def purge!
|
78
|
+
serial_processor(filter_container_names) { |container| Actions::Purge.new(container).execute! }
|
63
79
|
end
|
64
80
|
|
65
81
|
def valid?
|
@@ -71,13 +87,56 @@ module Percheron
|
|
71
87
|
attr_reader :config, :stack_name
|
72
88
|
|
73
89
|
def stack_config
|
74
|
-
@stack_config ||= config.stacks[stack_name] || Hashie::Mash.new({})
|
90
|
+
@stack_config ||= (config.stacks[stack_name] || Hashie::Mash.new({}))
|
75
91
|
end
|
76
92
|
|
77
|
-
def
|
78
|
-
containers.
|
93
|
+
def filter_container_names(container_names=[])
|
94
|
+
stack_config.containers.map do |container_config|
|
95
|
+
if container_names.empty? || container_names.include?(container_config.name)
|
96
|
+
container_config.name
|
97
|
+
end
|
98
|
+
end.compact
|
99
|
+
end
|
100
|
+
|
101
|
+
def exec_on_containers(container_names)
|
102
|
+
filter_containers(container_names).each { |_, container| yield(container) }
|
103
|
+
end
|
104
|
+
|
105
|
+
def serial_processor(container_names)
|
106
|
+
exec_on_containers(container_names) do |container|
|
79
107
|
yield(container)
|
108
|
+
container_names.delete(container.name)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def containers_affected(container_names)
|
113
|
+
deps = []
|
114
|
+
container_names.each do |container_name|
|
115
|
+
filter_containers.each do |_, container|
|
116
|
+
deps << container.name if container.dependant_container_names.include?(container_name)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
deps
|
120
|
+
end
|
121
|
+
|
122
|
+
def containers_and_their_dependants(container_names)
|
123
|
+
all_containers = filter_containers
|
124
|
+
container_names.inject({}) do |all, container_name|
|
125
|
+
all[container_name] = all_containers[container_name].dependant_container_names
|
126
|
+
all
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def dependant_containers(container_names)
|
131
|
+
container_names = filter_container_names(container_names)
|
132
|
+
|
133
|
+
wip_list = []
|
134
|
+
containers_and_their_dependants(container_names).each do |container_name, dependant_container_names|
|
135
|
+
wip_list += dependant_container_names unless dependant_container_names.empty?
|
136
|
+
wip_list << container_name
|
80
137
|
end
|
138
|
+
wip_list.uniq
|
81
139
|
end
|
140
|
+
|
82
141
|
end
|
83
142
|
end
|
@@ -10,7 +10,7 @@ module Percheron
|
|
10
10
|
message = rules.return { |rule| send(rule) }
|
11
11
|
|
12
12
|
if message
|
13
|
-
raise Errors::ContainerInvalid.new(message)
|
13
|
+
raise Errors::ContainerInvalid.new(formatted_message(message))
|
14
14
|
else
|
15
15
|
true
|
16
16
|
end
|
@@ -20,6 +20,14 @@ module Percheron
|
|
20
20
|
|
21
21
|
attr_reader :container
|
22
22
|
|
23
|
+
def formatted_message(message)
|
24
|
+
if container.name
|
25
|
+
"Container config for '%s' is invalid: %s" % [ container.name, message ]
|
26
|
+
else
|
27
|
+
"Container config is invalid: %s" % [ message ]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
23
31
|
def rules
|
24
32
|
[
|
25
33
|
:validate_name,
|
data/lib/percheron/version.rb
CHANGED
data/percheron.gemspec
CHANGED
@@ -25,10 +25,12 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_runtime_dependency 'naught', '~> 1.0'
|
26
26
|
spec.add_runtime_dependency 'semantic', '~> 1.4'
|
27
27
|
spec.add_runtime_dependency 'metastore', '~> 0.3'
|
28
|
+
spec.add_runtime_dependency 'highline', '~> 1.7.1'
|
28
29
|
|
29
30
|
spec.add_development_dependency 'bundler', '~> 1.7'
|
30
31
|
spec.add_development_dependency 'rake', '~> 10.0'
|
31
32
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
33
|
+
spec.add_development_dependency 'guard-rspec', '~> 4.5'
|
32
34
|
spec.add_development_dependency 'simplecov', '~> 0.9'
|
33
35
|
spec.add_development_dependency 'timecop', '~> 0.7'
|
34
36
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: percheron
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ash McKenzie
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: clamp
|
@@ -108,6 +108,20 @@ dependencies:
|
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0.3'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: highline
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 1.7.1
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 1.7.1
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
126
|
name: bundler
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -150,6 +164,20 @@ dependencies:
|
|
150
164
|
- - "~>"
|
151
165
|
- !ruby/object:Gem::Version
|
152
166
|
version: '3.0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: guard-rspec
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '4.5'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '4.5'
|
153
181
|
- !ruby/object:Gem::Dependency
|
154
182
|
name: simplecov
|
155
183
|
requirement: !ruby/object:Gem::Requirement
|
@@ -191,18 +219,31 @@ files:
|
|
191
219
|
- ".travis.yml"
|
192
220
|
- CODE_OF_CONDUCT.md
|
193
221
|
- Gemfile
|
222
|
+
- Guardfile
|
194
223
|
- LICENSE.txt
|
195
224
|
- README.md
|
196
225
|
- Rakefile
|
197
226
|
- assets/percheron.png
|
198
227
|
- bin/percheron
|
199
228
|
- lib/percheron.rb
|
229
|
+
- lib/percheron/actions.rb
|
230
|
+
- lib/percheron/actions/base.rb
|
231
|
+
- lib/percheron/actions/build.rb
|
232
|
+
- lib/percheron/actions/create.rb
|
233
|
+
- lib/percheron/actions/exec.rb
|
234
|
+
- lib/percheron/actions/purge.rb
|
235
|
+
- lib/percheron/actions/recreate.rb
|
236
|
+
- lib/percheron/actions/rename.rb
|
237
|
+
- lib/percheron/actions/restart.rb
|
238
|
+
- lib/percheron/actions/start.rb
|
239
|
+
- lib/percheron/actions/stop.rb
|
200
240
|
- lib/percheron/cli.rb
|
201
241
|
- lib/percheron/cli/abstract_command.rb
|
202
242
|
- lib/percheron/cli/console_command.rb
|
203
243
|
- lib/percheron/cli/create_command.rb
|
204
244
|
- lib/percheron/cli/list_command.rb
|
205
245
|
- lib/percheron/cli/main_command.rb
|
246
|
+
- lib/percheron/cli/purge_command.rb
|
206
247
|
- lib/percheron/cli/recreate_command.rb
|
207
248
|
- lib/percheron/cli/restart_command.rb
|
208
249
|
- lib/percheron/cli/start_command.rb
|
@@ -210,21 +251,14 @@ files:
|
|
210
251
|
- lib/percheron/config.rb
|
211
252
|
- lib/percheron/config_delegator.rb
|
212
253
|
- lib/percheron/container.rb
|
213
|
-
- lib/percheron/container/actions.rb
|
214
|
-
- lib/percheron/container/actions/base.rb
|
215
|
-
- lib/percheron/container/actions/build.rb
|
216
|
-
- lib/percheron/container/actions/create.rb
|
217
|
-
- lib/percheron/container/actions/recreate.rb
|
218
|
-
- lib/percheron/container/actions/start.rb
|
219
|
-
- lib/percheron/container/actions/stop.rb
|
220
|
-
- lib/percheron/container/main.rb
|
221
|
-
- lib/percheron/container/null.rb
|
222
254
|
- lib/percheron/core_extensions.rb
|
223
255
|
- lib/percheron/docker_connection.rb
|
224
256
|
- lib/percheron/errors.rb
|
225
257
|
- lib/percheron/formatters.rb
|
226
258
|
- lib/percheron/formatters/stack.rb
|
227
259
|
- lib/percheron/formatters/stack/table.rb
|
260
|
+
- lib/percheron/null_container.rb
|
261
|
+
- lib/percheron/oh_dear.rb
|
228
262
|
- lib/percheron/stack.rb
|
229
263
|
- lib/percheron/validators.rb
|
230
264
|
- lib/percheron/validators/config.rb
|
@@ -1,15 +0,0 @@
|
|
1
|
-
require 'open3'
|
2
|
-
|
3
|
-
require 'percheron/container/actions/base'
|
4
|
-
require 'percheron/container/actions/stop'
|
5
|
-
require 'percheron/container/actions/start'
|
6
|
-
require 'percheron/container/actions/create'
|
7
|
-
require 'percheron/container/actions/recreate'
|
8
|
-
require 'percheron/container/actions/build'
|
9
|
-
|
10
|
-
module Percheron
|
11
|
-
module Container
|
12
|
-
module Actions
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
module Percheron
|
2
|
-
module Container
|
3
|
-
module Actions
|
4
|
-
module Base
|
5
|
-
|
6
|
-
private
|
7
|
-
|
8
|
-
def base_dir
|
9
|
-
container.dockerfile.dirname.to_s
|
10
|
-
end
|
11
|
-
|
12
|
-
def in_working_directory(new_dir)
|
13
|
-
old_dir = Dir.pwd
|
14
|
-
Dir.chdir(new_dir)
|
15
|
-
yield
|
16
|
-
Dir.chdir(old_dir)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
@@ -1,58 +0,0 @@
|
|
1
|
-
module Percheron
|
2
|
-
module Container
|
3
|
-
module Actions
|
4
|
-
class Build
|
5
|
-
|
6
|
-
include Base
|
7
|
-
|
8
|
-
def initialize(container, nocache: false)
|
9
|
-
@container = container
|
10
|
-
@nocache = nocache
|
11
|
-
end
|
12
|
-
|
13
|
-
def execute!
|
14
|
-
build!
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
attr_reader :container, :nocache
|
20
|
-
|
21
|
-
def build_opts
|
22
|
-
{
|
23
|
-
'dockerfile' => container.dockerfile.basename.to_s,
|
24
|
-
't' => container.image_name,
|
25
|
-
'forcerm' => true,
|
26
|
-
'nocache' => nocache
|
27
|
-
}
|
28
|
-
end
|
29
|
-
|
30
|
-
def build!
|
31
|
-
in_working_directory(base_dir) do
|
32
|
-
execute_pre_build_scripts!
|
33
|
-
|
34
|
-
$logger.debug "Building '#{container.image_name}'"
|
35
|
-
Docker::Image.build_from_dir(base_dir, build_opts) do |out|
|
36
|
-
$logger.debug '%s' % [ out.strip ]
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def execute_pre_build_scripts!
|
42
|
-
container.pre_build_scripts.each do |script|
|
43
|
-
in_working_directory(base_dir) do
|
44
|
-
command = '/bin/bash -x %s 2>&1' % Pathname.new(File.expand_path(script))
|
45
|
-
$logger.debug "Executing PRE build '#{command}' for '#{container.name}' container"
|
46
|
-
Open3.popen2e(command) do |stdin, stdout_err, wait_thr|
|
47
|
-
while line = stdout_err.gets
|
48
|
-
$logger.debug line.strip
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|