percheron 0.7.16 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +0 -4
- data/CHANGELOG.md +8 -0
- data/Guardfile +1 -1
- data/lib/percheron/actions/build.rb +14 -7
- data/lib/percheron/actions/create.rb +50 -39
- data/lib/percheron/actions/exec.rb +8 -9
- data/lib/percheron/actions/exec_local.rb +1 -2
- data/lib/percheron/actions/purge.rb +18 -13
- data/lib/percheron/actions/restart.rb +1 -2
- data/lib/percheron/actions/shell.rb +4 -4
- data/lib/percheron/actions/start.rb +5 -6
- data/lib/percheron/actions/stop.rb +0 -1
- data/lib/percheron/actions.rb +0 -1
- data/lib/percheron/commands/abstract.rb +11 -6
- data/lib/percheron/commands/build.rb +3 -2
- data/lib/percheron/commands/console.rb +0 -5
- data/lib/percheron/commands/create.rb +7 -2
- data/lib/percheron/commands/logs.rb +1 -1
- data/lib/percheron/commands/main.rb +3 -4
- data/lib/percheron/commands/purge.rb +11 -2
- data/lib/percheron/commands/restart.rb +1 -1
- data/lib/percheron/commands/shell.rb +1 -1
- data/lib/percheron/commands/start.rb +1 -1
- data/lib/percheron/commands/stop.rb +1 -1
- data/lib/percheron/commands.rb +0 -1
- data/lib/percheron/config.rb +8 -5
- data/lib/percheron/errors.rb +1 -0
- data/lib/percheron/graph.rb +3 -4
- data/lib/percheron/logger.rb +1 -1
- data/lib/percheron/stack.rb +44 -41
- data/lib/percheron/unit/image_helper.rb +33 -0
- data/lib/percheron/unit.rb +18 -35
- data/lib/percheron/version.rb +1 -1
- data/lib/percheron.rb +1 -0
- data/percheron.gemspec +1 -1
- metadata +5 -6
- data/lib/percheron/actions/recreate.rb +0 -51
- data/lib/percheron/commands/recreate.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4c4858cd5f4ec9b26b7976179c56f074a1cb5570
|
4
|
+
data.tar.gz: 050b74b700b9c127766e5454eba7aea97c85ba7c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9865aad4f0d56c8e2607bd74dc579443d7c645afc20c1362b855ad867c09475080d5588ffcdf89f86ed89e5cf7ab0e3791b2f85cc8e91565b54fda597198ecb0
|
7
|
+
data.tar.gz: 438581d49d52687a2d06cf5d6bd538b3f1bf0df2dfe7b5dab655e1b2bd5a87f62fa5a194f559a3b41dfdf5bebeb32f54aadc24c0a4be3bdc5f6f510ee7bd31ef
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
## v0.8.0 / 2015-08-19
|
2
|
+
|
3
|
+
* Hostname is the full `<stack_name>_<name>` by default
|
4
|
+
* Support for defining restart policy for each unit
|
5
|
+
* Support privileged mode
|
6
|
+
* Tidied up (re)create, (re)build and log commands
|
7
|
+
* Improved logging and error handling
|
8
|
+
|
1
9
|
## v0.7.16 / 2015-08-07
|
2
10
|
|
3
11
|
* Improved graph look
|
data/Guardfile
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
module Percheron
|
2
2
|
module Actions
|
3
3
|
class Build
|
4
|
-
|
5
4
|
include Base
|
6
5
|
|
7
|
-
def initialize(unit,
|
6
|
+
def initialize(unit, usecache: true, forcerm: false, exec_scripts: true)
|
8
7
|
@unit = unit
|
9
|
-
@
|
8
|
+
@usecache = usecache
|
10
9
|
@forcerm = forcerm
|
11
10
|
@exec_scripts = exec_scripts
|
12
11
|
end
|
@@ -22,15 +21,17 @@ module Percheron
|
|
22
21
|
|
23
22
|
private
|
24
23
|
|
25
|
-
attr_reader :unit, :
|
24
|
+
attr_reader :unit, :usecache, :forcerm, :exec_scripts
|
25
|
+
alias_method :usecache?, :usecache
|
26
|
+
alias_method :forcerm?, :forcerm
|
26
27
|
alias_method :exec_scripts?, :exec_scripts
|
27
28
|
|
28
29
|
def options
|
29
30
|
{
|
30
31
|
'dockerfile' => dockerfile,
|
31
32
|
't' => unit.image_name,
|
32
|
-
'forcerm' => forcerm
|
33
|
-
'nocache' =>
|
33
|
+
'forcerm' => forcerm?,
|
34
|
+
'nocache' => !usecache?
|
34
35
|
}
|
35
36
|
end
|
36
37
|
|
@@ -67,13 +68,19 @@ module Percheron
|
|
67
68
|
execute_pre_build_scripts!
|
68
69
|
$logger.info "Building '#{unit.image_name}' image"
|
69
70
|
Connection.perform(Docker::Image, :build_from_dir, base_dir, options) do |out|
|
70
|
-
$logger.
|
71
|
+
$logger.info '%s' % [ extract_content(out) ]
|
71
72
|
end
|
72
73
|
end
|
73
74
|
ensure
|
74
75
|
remove_temp_dockerfile!
|
75
76
|
end
|
76
77
|
|
78
|
+
def extract_content(out)
|
79
|
+
json = JSON.parse(out)
|
80
|
+
return '' unless json['stream']
|
81
|
+
json['stream'].strip
|
82
|
+
end
|
83
|
+
|
77
84
|
def execute_pre_build_scripts!
|
78
85
|
return nil if !exec_scripts? && unit.pre_build_scripts.empty?
|
79
86
|
ExecLocal.new(unit, unit.pre_build_scripts, 'PRE build').execute!
|
@@ -1,36 +1,32 @@
|
|
1
1
|
module Percheron
|
2
2
|
module Actions
|
3
3
|
class Create
|
4
|
-
|
5
4
|
include Base
|
6
5
|
|
7
|
-
def initialize(unit, start: false,
|
6
|
+
def initialize(unit, build: true, start: false, force: false, cmd: false)
|
8
7
|
@unit = unit
|
8
|
+
@build = build
|
9
9
|
@start = start
|
10
|
-
@
|
11
|
-
@cmd = cmd
|
12
|
-
@unit_image_existed = unit.image_exists?
|
10
|
+
@force = force
|
11
|
+
@cmd = (cmd || unit.start_args)
|
13
12
|
end
|
14
13
|
|
15
14
|
def execute!
|
16
15
|
results = []
|
17
|
-
|
18
|
-
|
19
|
-
else
|
20
|
-
results << create!
|
21
|
-
end
|
16
|
+
results << build_or_pull_image!
|
17
|
+
results << create!
|
22
18
|
results.compact.empty? ? nil : unit
|
23
19
|
end
|
24
20
|
|
25
21
|
private
|
26
22
|
|
27
|
-
attr_reader :unit, :start, :
|
23
|
+
attr_reader :unit, :build, :start, :force, :cmd
|
24
|
+
alias_method :build?, :build
|
28
25
|
alias_method :start?, :start
|
29
|
-
alias_method :
|
30
|
-
alias_method :unit_image_existed?, :unit_image_existed
|
26
|
+
alias_method :force?, :force
|
31
27
|
|
32
|
-
def
|
33
|
-
|
28
|
+
def create?
|
29
|
+
unit.startable? && (!unit.exists? || force)
|
34
30
|
end
|
35
31
|
|
36
32
|
def base_options
|
@@ -46,19 +42,25 @@ module Percheron
|
|
46
42
|
end
|
47
43
|
|
48
44
|
def host_config_options
|
49
|
-
|
50
|
-
'HostConfig'
|
45
|
+
{
|
46
|
+
'HostConfig' => {
|
51
47
|
'PortBindings' => port_bindings,
|
52
48
|
'Links' => unit.links,
|
53
|
-
'Binds' => unit.volumes
|
49
|
+
'Binds' => unit.volumes,
|
50
|
+
'RestartPolicy' => unit.restart_policy,
|
51
|
+
'Privileged' => unit.privileged
|
54
52
|
}
|
55
53
|
}
|
56
|
-
|
57
|
-
|
54
|
+
end
|
55
|
+
|
56
|
+
def host_config_dns_options
|
57
|
+
unit.dns.empty? ? {} : { 'HostConfig' => { 'Dns' => unit.dns } }
|
58
58
|
end
|
59
59
|
|
60
60
|
def options
|
61
|
-
@options ||=
|
61
|
+
@options ||= begin
|
62
|
+
base_options.merge(host_config_options).merge(host_config_dns_options)
|
63
|
+
end
|
62
64
|
end
|
63
65
|
|
64
66
|
def port_bindings
|
@@ -68,49 +70,58 @@ module Percheron
|
|
68
70
|
end
|
69
71
|
end
|
70
72
|
|
71
|
-
def
|
73
|
+
def build_or_pull_image!
|
72
74
|
unit.buildable? ? build_image! : pull_image!
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
75
|
+
end
|
76
|
+
|
77
|
+
def create!
|
78
|
+
if create?
|
79
|
+
create_unit!
|
80
|
+
update_dockerfile_md5!
|
81
|
+
start_and_insert_scripts! if start?
|
82
|
+
else
|
83
|
+
$logger.warn("Unit '#{unit.display_name}' already exists (--force to overwrite)")
|
84
|
+
end
|
85
|
+
rescue Errors::DockerContainerCannotDelete => e
|
86
|
+
$logger.error "Unable to delete '%s' unit - %s" % [ unit.name, e.inspect ]
|
78
87
|
end
|
79
88
|
|
80
89
|
def build_image!
|
81
|
-
Build.new(unit).execute!
|
90
|
+
Build.new(unit).execute! if build?
|
82
91
|
end
|
83
92
|
|
84
|
-
# FIXME: move this
|
85
93
|
def pull_image!
|
86
94
|
return nil if unit.image_exists?
|
87
95
|
$logger.info "Pulling '#{unit.image_name}' image"
|
88
96
|
Connection.perform(Docker::Image, :create, fromImage: unit.image_name) do |out|
|
89
|
-
$logger.
|
97
|
+
$logger.info JSON.parse(out)
|
90
98
|
end
|
91
99
|
end
|
92
100
|
|
101
|
+
def delete_unit!
|
102
|
+
$logger.info "Deleting '#{unit.display_name}' unit"
|
103
|
+
unit.container.remove(force: force?)
|
104
|
+
rescue Docker::Error::ConflictError => e
|
105
|
+
raise(Errors::DockerContainerCannotDelete.new, e)
|
106
|
+
end
|
107
|
+
|
93
108
|
def create_unit!
|
109
|
+
delete_unit! if force?
|
94
110
|
$logger.info "Creating '#{unit.display_name}' unit"
|
95
111
|
Connection.perform(Docker::Container, :create, options)
|
96
112
|
end
|
97
113
|
|
98
|
-
def
|
99
|
-
return nil if !unit.startable? || !start?
|
114
|
+
def start_and_insert_scripts!
|
100
115
|
Start.new(unit).execute!
|
116
|
+
insert_post_start_scripts!
|
101
117
|
end
|
102
118
|
|
103
119
|
def update_dockerfile_md5!
|
104
120
|
unit.update_dockerfile_md5!
|
105
121
|
end
|
106
122
|
|
107
|
-
def
|
108
|
-
|
109
|
-
insert_files!(unit.post_start_scripts)
|
110
|
-
end
|
111
|
-
|
112
|
-
def insert_files!(files)
|
113
|
-
files.each { |file| insert_file!(file) }
|
123
|
+
def insert_post_start_scripts!
|
124
|
+
unit.post_start_scripts.each { |file| insert_file!(file) }
|
114
125
|
end
|
115
126
|
|
116
127
|
def insert_file!(file)
|
@@ -1,12 +1,11 @@
|
|
1
1
|
module Percheron
|
2
2
|
module Actions
|
3
3
|
class Exec
|
4
|
-
|
5
4
|
include Base
|
6
5
|
|
7
|
-
def initialize(unit,
|
6
|
+
def initialize(unit, needed_units, scripts, description)
|
8
7
|
@unit = unit
|
9
|
-
@
|
8
|
+
@needed_units = needed_units
|
10
9
|
@scripts = scripts
|
11
10
|
@description = description
|
12
11
|
end
|
@@ -19,13 +18,13 @@ module Percheron
|
|
19
18
|
|
20
19
|
private
|
21
20
|
|
22
|
-
attr_reader :unit, :
|
21
|
+
attr_reader :unit, :needed_units, :scripts, :description
|
23
22
|
|
24
23
|
def exec!
|
25
24
|
results = []
|
26
|
-
|
25
|
+
started_needed_units = start_units!(needed_units)
|
27
26
|
results << execute_scripts_on_running_unit!
|
28
|
-
results << stop_units!(
|
27
|
+
results << stop_units!(started_needed_units)
|
29
28
|
results
|
30
29
|
end
|
31
30
|
|
@@ -34,7 +33,7 @@ module Percheron
|
|
34
33
|
Start.new(unit, exec_scripts: false).execute! unless unit_running
|
35
34
|
execute_scripts!
|
36
35
|
commit_and_tag_new_image!
|
37
|
-
Stop.new(unit).execute!
|
36
|
+
Stop.new(unit).execute! unless unit_running
|
38
37
|
end
|
39
38
|
|
40
39
|
def commit_and_tag_new_image!
|
@@ -67,8 +66,8 @@ module Percheron
|
|
67
66
|
def start_units!(units, scripts: true)
|
68
67
|
exec_on_units!(units) do |unit|
|
69
68
|
next if unit.running?
|
70
|
-
units = unit.
|
71
|
-
Start.new(unit,
|
69
|
+
units = unit.startable_needed_units.values
|
70
|
+
Start.new(unit, needed_units: units, exec_scripts: scripts).execute!
|
72
71
|
end
|
73
72
|
end
|
74
73
|
|
@@ -3,7 +3,6 @@ require 'open3'
|
|
3
3
|
module Percheron
|
4
4
|
module Actions
|
5
5
|
class ExecLocal
|
6
|
-
|
7
6
|
include Base
|
8
7
|
|
9
8
|
def initialize(unit, scripts, description)
|
@@ -26,7 +25,7 @@ module Percheron
|
|
26
25
|
$logger.debug "Executing #{description} scripts '#{scripts.inspect}' locally"
|
27
26
|
scripts.each do |script|
|
28
27
|
in_working_directory(base_dir) do
|
29
|
-
execute_command!('/bin/sh -x %s 2>&1' % Pathname.new(File.expand_path(script)))
|
28
|
+
execute_command!('/bin/sh -x %s 2>&1' % [ Pathname.new(File.expand_path(script)) ])
|
30
29
|
end
|
31
30
|
end
|
32
31
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module Percheron
|
2
2
|
module Actions
|
3
3
|
class Purge
|
4
|
-
|
5
4
|
include Base
|
6
5
|
|
7
6
|
def initialize(unit, force: false)
|
@@ -12,8 +11,8 @@ module Percheron
|
|
12
11
|
def execute!
|
13
12
|
results = []
|
14
13
|
results << stop!
|
15
|
-
results << delete_unit!
|
16
|
-
results << delete_image!
|
14
|
+
results << delete_unit! if delete_unit?
|
15
|
+
results << delete_image! if delete_image?
|
17
16
|
results.compact.empty? ? nil : unit
|
18
17
|
end
|
19
18
|
|
@@ -25,26 +24,32 @@ module Percheron
|
|
25
24
|
Stop.new(unit).execute!
|
26
25
|
end
|
27
26
|
|
27
|
+
def delete_unit?
|
28
|
+
unit.exists?
|
29
|
+
end
|
30
|
+
|
28
31
|
def delete_image?
|
29
32
|
unit.image_exists? && unit.buildable?
|
30
33
|
end
|
31
34
|
|
35
|
+
def opts
|
36
|
+
{ force: force }
|
37
|
+
end
|
38
|
+
|
32
39
|
def delete_unit!
|
33
|
-
|
34
|
-
$logger.info "Deleting '#{unit.display_name}' unit"
|
35
|
-
unit.container.remove(force: force)
|
36
|
-
rescue Docker::Error::ConflictError => e
|
37
|
-
$logger.error "Unable to delete '%s' unit - %s" % [ unit.name, e.inspect ]
|
40
|
+
delete!('unit', unit.display_name) { unit.container.remove(opts) }
|
38
41
|
end
|
39
42
|
|
40
43
|
def delete_image!
|
41
|
-
|
42
|
-
$logger.info "Deleting '#{unit.image_name}' image"
|
43
|
-
unit.image.remove(force: force)
|
44
|
-
rescue Docker::Error::ConflictError => e
|
45
|
-
$logger.error "Unable to delete '%s' image - %s" % [ unit.image_name, e.inspect ]
|
44
|
+
delete!('image', unit.image_name) { unit.image.remove(opts) }
|
46
45
|
end
|
47
46
|
|
47
|
+
def delete!(type, value)
|
48
|
+
$logger.info("Deleting '%s' %s" % [ value, type ])
|
49
|
+
yield
|
50
|
+
rescue Docker::Error::ConflictError => e
|
51
|
+
$logger.error("Unable to delete '%s' %s - %s" % [ value, type, e.inspect ])
|
52
|
+
end
|
48
53
|
end
|
49
54
|
end
|
50
55
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module Percheron
|
2
2
|
module Actions
|
3
3
|
class Restart
|
4
|
-
|
5
4
|
include Base
|
6
5
|
|
7
6
|
def initialize(unit)
|
@@ -24,7 +23,7 @@ module Percheron
|
|
24
23
|
end
|
25
24
|
|
26
25
|
def start!
|
27
|
-
opts = {
|
26
|
+
opts = { needed_units: unit.startable_needed_units.values }
|
28
27
|
Start.new(unit, opts).execute!
|
29
28
|
end
|
30
29
|
|
@@ -6,9 +6,9 @@ module Percheron
|
|
6
6
|
DEFAULT_COMMAND = '/bin/sh'
|
7
7
|
DOCKER_CLIENT = 'docker'
|
8
8
|
|
9
|
-
def initialize(unit,
|
9
|
+
def initialize(unit, raw_command: DEFAULT_COMMAND)
|
10
10
|
@unit = unit
|
11
|
-
@
|
11
|
+
@raw_command = raw_command
|
12
12
|
end
|
13
13
|
|
14
14
|
def execute!
|
@@ -17,14 +17,14 @@ module Percheron
|
|
17
17
|
|
18
18
|
private
|
19
19
|
|
20
|
-
attr_reader :unit
|
20
|
+
attr_reader :unit, :raw_command
|
21
21
|
|
22
22
|
def valid?
|
23
23
|
Validators::DockerClient.new.valid?
|
24
24
|
end
|
25
25
|
|
26
26
|
def command
|
27
|
-
"sh -c '%s'" %
|
27
|
+
"sh -c '%s'" % [ raw_command ]
|
28
28
|
end
|
29
29
|
|
30
30
|
def exec!
|
@@ -1,12 +1,11 @@
|
|
1
1
|
module Percheron
|
2
2
|
module Actions
|
3
3
|
class Start
|
4
|
-
|
5
4
|
include Base
|
6
5
|
|
7
|
-
def initialize(unit,
|
6
|
+
def initialize(unit, needed_units: [], cmd: false, exec_scripts: true)
|
8
7
|
@unit = unit
|
9
|
-
@
|
8
|
+
@needed_units = needed_units
|
10
9
|
@cmd = cmd
|
11
10
|
@exec_scripts = exec_scripts
|
12
11
|
end
|
@@ -23,7 +22,7 @@ module Percheron
|
|
23
22
|
|
24
23
|
private
|
25
24
|
|
26
|
-
attr_reader :unit, :
|
25
|
+
attr_reader :unit, :needed_units, :cmd, :exec_scripts
|
27
26
|
|
28
27
|
def exec_scripts?
|
29
28
|
!unit.post_start_scripts.empty? && exec_scripts
|
@@ -31,7 +30,7 @@ module Percheron
|
|
31
30
|
|
32
31
|
def create!
|
33
32
|
return nil if unit.exists?
|
34
|
-
Create.new(unit, cmd: cmd
|
33
|
+
Create.new(unit, cmd: cmd).execute!
|
35
34
|
end
|
36
35
|
|
37
36
|
def start!
|
@@ -42,7 +41,7 @@ module Percheron
|
|
42
41
|
|
43
42
|
def execute_post_start_scripts!
|
44
43
|
scripts = unit.post_start_scripts
|
45
|
-
Exec.new(unit,
|
44
|
+
Exec.new(unit, needed_units, scripts, 'POST start').execute! if exec_scripts?
|
46
45
|
end
|
47
46
|
|
48
47
|
end
|
data/lib/percheron/actions.rb
CHANGED
@@ -3,7 +3,6 @@ require 'percheron/actions/stop'
|
|
3
3
|
require 'percheron/actions/start'
|
4
4
|
require 'percheron/actions/restart'
|
5
5
|
require 'percheron/actions/create'
|
6
|
-
require 'percheron/actions/recreate'
|
7
6
|
require 'percheron/actions/build'
|
8
7
|
require 'percheron/actions/purge'
|
9
8
|
require 'percheron/actions/exec'
|
@@ -17,16 +17,24 @@ module Percheron
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
def
|
21
|
-
|
22
|
-
|
20
|
+
def runit
|
21
|
+
yield
|
22
|
+
rescue Docker::Error::UnexpectedResponseError => e
|
23
|
+
$logger.error('')
|
24
|
+
$logger.error('An exception occurred :(')
|
25
|
+
$logger.error('')
|
26
|
+
$logger.error(e.inspect)
|
23
27
|
end
|
24
28
|
|
25
29
|
def execute
|
26
30
|
stack.valid?
|
31
|
+
rescue Errno::ENOENT, Errors::ConfigFileInvalid, Errors::StackInvalid => e
|
32
|
+
signal_usage_error(e.message)
|
33
|
+
exit(1)
|
27
34
|
rescue => e
|
28
35
|
puts "%s\n\n%s\n\n" % [ e.inspect, e.backtrace.join("\n") ]
|
29
36
|
signal_usage_error(e.message)
|
37
|
+
exit(1)
|
30
38
|
end
|
31
39
|
|
32
40
|
def stack
|
@@ -40,9 +48,6 @@ module Percheron
|
|
40
48
|
Percheron::Connection.load!(c)
|
41
49
|
end
|
42
50
|
end
|
43
|
-
rescue Errors::ConfigFileInvalid => e
|
44
|
-
$logger.error e.inspect
|
45
|
-
exit(1)
|
46
51
|
end
|
47
52
|
end
|
48
53
|
end
|
@@ -3,11 +3,12 @@ module Percheron
|
|
3
3
|
class Build < Abstract
|
4
4
|
|
5
5
|
default_parameters!
|
6
|
-
option('--
|
6
|
+
option('--usecache', :flag, 'Use image cache', default: true)
|
7
|
+
option('--forcerm', :flag, 'Force removal of intermediate containers', default: false)
|
7
8
|
|
8
9
|
def execute
|
9
10
|
super
|
10
|
-
stack.build!(unit_names: unit_names, forcerm: forcerm?)
|
11
|
+
runit { stack.build!(unit_names: unit_names, usecache: usecache?, forcerm: forcerm?) }
|
11
12
|
end
|
12
13
|
end
|
13
14
|
end
|
@@ -2,11 +2,16 @@ module Percheron
|
|
2
2
|
module Commands
|
3
3
|
class Create < Abstract
|
4
4
|
|
5
|
-
|
5
|
+
default_parameters!
|
6
|
+
option('--start', :flag, '(Re)start unit once created', default: true)
|
7
|
+
option('--build', :flag, '(Re)build image', default: true)
|
8
|
+
option('--deep', :flag, 'Include needed units', default: false)
|
9
|
+
option('--force', :flag, 'Force unit (re)creation', default: false)
|
6
10
|
|
7
11
|
def execute
|
8
12
|
super
|
9
|
-
|
13
|
+
opts = { unit_names: unit_names, build: build?, start: start?, deep: deep?, force: force? }
|
14
|
+
runit { stack.create!(opts) }
|
10
15
|
end
|
11
16
|
end
|
12
17
|
end
|
@@ -4,7 +4,7 @@ module Percheron
|
|
4
4
|
|
5
5
|
parameter('STACK_NAME', 'stack name', required: true)
|
6
6
|
parameter('UNIT_NAME', 'unit name', required: true)
|
7
|
-
option('--follow', :flag, '
|
7
|
+
option([ '-f', '-t', '--follow', '--tail' ], :flag, 'Follow the logs', default: false)
|
8
8
|
|
9
9
|
def execute
|
10
10
|
super
|
@@ -2,13 +2,12 @@ module Percheron
|
|
2
2
|
module Commands
|
3
3
|
class Main < Abstract
|
4
4
|
subcommand %w(list status), 'List stacks and its units', List
|
5
|
-
subcommand 'console', '
|
5
|
+
subcommand 'console', '', Console
|
6
6
|
subcommand 'start', 'Start a stack', Start
|
7
7
|
subcommand 'stop', 'Stop a stack', Stop
|
8
8
|
subcommand 'restart', 'Restart a stack', Restart
|
9
|
-
subcommand
|
10
|
-
subcommand
|
11
|
-
subcommand 'recreate', 'Recreate a stack', Recreate
|
9
|
+
subcommand %w(build rebuild), '(Re)build image(s) for a stack', Build
|
10
|
+
subcommand %w(create recreate), '(Re)build image(s) and (re)create units for a stack', Create
|
12
11
|
subcommand 'purge', 'Purge a stack', Purge
|
13
12
|
subcommand 'shell', 'Shell into a unit', Shell
|
14
13
|
subcommand 'logs', 'Show logs for a unit', Logs
|
@@ -3,12 +3,21 @@ module Percheron
|
|
3
3
|
class Purge < Abstract
|
4
4
|
|
5
5
|
default_parameters!
|
6
|
-
option(
|
6
|
+
option('--yes', :flag, 'Yes, purge image / unit', default: false)
|
7
|
+
option('--force', :flag, 'Force image / unit removal', default: false)
|
7
8
|
|
8
9
|
def execute
|
9
10
|
super
|
10
|
-
stack.purge!(unit_names: unit_names, force: force?)
|
11
|
+
runit { stack.purge!(unit_names: unit_names, force: force?) if yes? || confirm? }
|
11
12
|
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def confirm?
|
17
|
+
ask('Are you sure? (y|n) ') do |q|
|
18
|
+
q.validate = /y(es)?|n(o)?/i
|
19
|
+
end.match(/y(es)?/i)
|
20
|
+
end
|
12
21
|
end
|
13
22
|
end
|
14
23
|
end
|
data/lib/percheron/commands.rb
CHANGED
@@ -9,7 +9,6 @@ require 'percheron/commands/purge'
|
|
9
9
|
require 'percheron/commands/console'
|
10
10
|
require 'percheron/commands/create'
|
11
11
|
require 'percheron/commands/build'
|
12
|
-
require 'percheron/commands/recreate'
|
13
12
|
require 'percheron/commands/shell'
|
14
13
|
require 'percheron/commands/logs'
|
15
14
|
require 'percheron/commands/graph'
|
data/lib/percheron/config.rb
CHANGED
@@ -78,7 +78,8 @@ module Percheron
|
|
78
78
|
@stacks = @yaml_contents = @raw_contents = @contents = nil
|
79
79
|
end
|
80
80
|
|
81
|
-
|
81
|
+
# FIXME: bugs here :(
|
82
|
+
def process_stacks!
|
82
83
|
stacks_by_name = contents.stacks.to_hash_by_key(:name)
|
83
84
|
scanned = scan_unit_configs(stacks_by_name)
|
84
85
|
stacks_by_name.each do |_, stack|
|
@@ -103,14 +104,15 @@ module Percheron
|
|
103
104
|
end
|
104
105
|
|
105
106
|
def replace_scanned(all, config, scanned)
|
106
|
-
match = config.fetch(:
|
107
|
+
match = config.fetch(:needed_unit_names, [])
|
107
108
|
unless (match & scanned.keys).empty?
|
108
|
-
config.
|
109
|
+
config.needed_unit_names = match.map { |v| scanned[v] }.flatten
|
109
110
|
end
|
110
111
|
all[config.name] = config
|
111
112
|
end
|
112
113
|
|
113
|
-
|
114
|
+
# FIXME
|
115
|
+
def scan_unit_configs(stacks_by_name)
|
114
116
|
all = {}
|
115
117
|
stacks_by_name.each do |_, stack|
|
116
118
|
stack.fetch(:units, []).each do |unit_config|
|
@@ -123,7 +125,8 @@ module Percheron
|
|
123
125
|
all
|
124
126
|
end
|
125
127
|
|
126
|
-
|
128
|
+
# FIXME
|
129
|
+
def expand_unit_config(unit_config, new_unit_names)
|
127
130
|
new_unit_names.each_with_object({}) do |new_name, all|
|
128
131
|
temp_unit_config = unit_config.dup
|
129
132
|
temp_unit_config.delete(:instances)
|
data/lib/percheron/errors.rb
CHANGED
data/lib/percheron/graph.rb
CHANGED
@@ -87,7 +87,7 @@ module Percheron
|
|
87
87
|
unit.ports.each do |ports|
|
88
88
|
label << '<font point-size="11">p: %s, i: %s</font>' % ports.split(':')
|
89
89
|
end
|
90
|
-
{ shape: shape, label: '<%s>' % label.join('<br/>'), fontname: 'arial' }
|
90
|
+
{ shape: shape, label: '<%s>' % [ label.join('<br/>') ], fontname: 'arial' }
|
91
91
|
end
|
92
92
|
|
93
93
|
def pseudo_node_opts(unit)
|
@@ -96,8 +96,8 @@ module Percheron
|
|
96
96
|
|
97
97
|
def add_links
|
98
98
|
units.each do |name, unit|
|
99
|
-
unit.
|
100
|
-
graph.add_edges(nodes[name], nodes[
|
99
|
+
unit.needed_units.each do |needed_name, needed_unit|
|
100
|
+
graph.add_edges(nodes[name], nodes[needed_name], node_link_opts(needed_unit))
|
101
101
|
end
|
102
102
|
end
|
103
103
|
end
|
@@ -108,6 +108,5 @@ module Percheron
|
|
108
108
|
color = unit.startable? ? 'black' : 'gray'
|
109
109
|
{ dir: direction, style: style, color: color }
|
110
110
|
end
|
111
|
-
|
112
111
|
end
|
113
112
|
end
|
data/lib/percheron/logger.rb
CHANGED
@@ -6,7 +6,7 @@ logger_level = Logger::INFO
|
|
6
6
|
logger_level = Logger::WARN if ENV['QUIET'] == 'true'
|
7
7
|
|
8
8
|
# :nocov:
|
9
|
-
if ENV['DEBUG']
|
9
|
+
if [ ENV['DEBUG'], ENV['DOCKER_DEBUG'] ].include?('true')
|
10
10
|
logger_level = Logger::DEBUG
|
11
11
|
Docker.logger = $logger if ENV['DOCKER_DEBUG'] == 'true'
|
12
12
|
end
|
data/lib/percheron/stack.rb
CHANGED
@@ -22,7 +22,7 @@ module Percheron
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def metastore_key
|
25
|
-
@metastore_key ||= 'stacks.%s' % name
|
25
|
+
@metastore_key ||= 'stacks.%s' % [ name ]
|
26
26
|
end
|
27
27
|
|
28
28
|
def unit_configs
|
@@ -30,7 +30,7 @@ module Percheron
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def units(unit_names = [])
|
33
|
-
unit_names =
|
33
|
+
unit_names = unit_names.empty? ? stack_units.keys : unit_names
|
34
34
|
unit_names.each_with_object({}) do |unit_name, all|
|
35
35
|
all[unit_name] = unit_from_name(unit_name)
|
36
36
|
end
|
@@ -38,11 +38,11 @@ module Percheron
|
|
38
38
|
|
39
39
|
def graph!(file)
|
40
40
|
Graph.new(self).save!(file)
|
41
|
-
$logger.info "Saved '%s'" % file
|
41
|
+
$logger.info "Saved '%s'" % [ file ]
|
42
42
|
end
|
43
43
|
|
44
|
-
def shell!(unit_name,
|
45
|
-
Actions::Shell.new(unit_from_name(unit_name),
|
44
|
+
def shell!(unit_name, raw_command: Percheron::Actions::Shell::DEFAULT_COMMAND)
|
45
|
+
Actions::Shell.new(unit_from_name(unit_name), raw_command: raw_command).execute!
|
46
46
|
end
|
47
47
|
|
48
48
|
def logs!(unit_name, follow: false)
|
@@ -50,50 +50,53 @@ module Percheron
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def stop!(unit_names: [])
|
53
|
+
unit_names = stack_units.keys if unit_names.empty?
|
53
54
|
execute!(Actions::Stop, filter_unit_names(unit_names).reverse)
|
54
55
|
end
|
55
56
|
|
56
|
-
# FIXME: bug when non-startable unit specified, all units started
|
57
57
|
def start!(unit_names: [])
|
58
|
-
unit_names =
|
59
|
-
|
60
|
-
|
61
|
-
|
58
|
+
unit_names = stack_units.keys if unit_names.empty?
|
59
|
+
unit_names = needed_units_for(unit_names)
|
60
|
+
exec_on_needed_units_for(unit_names) do |unit|
|
61
|
+
needed_units = unit.startable_needed_units.values
|
62
|
+
Actions::Start.new(unit, needed_units: needed_units).execute!
|
62
63
|
end
|
63
64
|
nil
|
64
65
|
end
|
65
66
|
|
66
67
|
def restart!(unit_names: [])
|
68
|
+
unit_names = stack_units.keys if unit_names.empty?
|
67
69
|
execute!(Actions::Restart, filter_unit_names(unit_names))
|
68
70
|
end
|
69
71
|
|
70
|
-
def build!(unit_names: [], forcerm: false)
|
71
|
-
unit_names =
|
72
|
-
|
73
|
-
|
72
|
+
def build!(unit_names: [], usecache: true, forcerm: false)
|
73
|
+
unit_names = stack_units.keys if unit_names.empty?
|
74
|
+
unit_names = needed_units_for(unit_names)
|
75
|
+
exec_on_needed_units_for(unit_names) do |unit|
|
76
|
+
Actions::Build.new(unit, usecache: usecache, forcerm: forcerm).execute!
|
74
77
|
end
|
75
78
|
nil
|
76
79
|
end
|
77
80
|
|
78
|
-
def create!(unit_names: [],
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
81
|
+
def create!(unit_names: [], build: true, start: false, deep: false, force: false)
|
82
|
+
opts = { build: build, start: start, force: force }
|
83
|
+
unit_names = if deep
|
84
|
+
unit_names = stack_units.keys if unit_names.empty?
|
85
|
+
needed_units_for(unit_names)
|
86
|
+
else
|
87
|
+
filter_unit_names(unit_names)
|
88
|
+
end
|
89
|
+
execute!(Actions::Create, unit_names, opts)
|
84
90
|
end
|
85
91
|
|
86
92
|
def purge!(unit_names: [], force: false)
|
93
|
+
unit_names = stack_units.keys if unit_names.empty?
|
87
94
|
execute!(Actions::Purge, filter_unit_names(unit_names).reverse, force: force)
|
88
95
|
end
|
89
96
|
|
90
97
|
def execute!(klass, unit_names, args=nil)
|
91
|
-
|
92
|
-
|
93
|
-
klass.new(unit, args).execute!
|
94
|
-
else
|
95
|
-
klass.new(unit).execute!
|
96
|
-
end
|
98
|
+
exec_on_needed_units_for(unit_names) do |unit|
|
99
|
+
args ? klass.new(unit, args).execute! : klass.new(unit).execute!
|
97
100
|
end
|
98
101
|
nil
|
99
102
|
end
|
@@ -110,20 +113,20 @@ module Percheron
|
|
110
113
|
@stack_config ||= (config.stacks[stack_name] || Hashie::Mash.new({}))
|
111
114
|
end
|
112
115
|
|
113
|
-
|
114
|
-
|
116
|
+
def stack_units
|
117
|
+
@stack_units ||= stack_config.fetch('units', {})
|
118
|
+
end
|
119
|
+
|
115
120
|
def filter_unit_names(unit_names = [])
|
116
|
-
|
117
|
-
if unit_names.
|
118
|
-
(unit_config.pseudo_name &&
|
119
|
-
unit_names.include?(unit_config.pseudo_name))
|
121
|
+
stack_units.map do |unit_name, unit_config|
|
122
|
+
if unit_names.include?(unit_name) ||
|
123
|
+
(unit_config.pseudo_name && unit_names.include?(unit_config.pseudo_name))
|
120
124
|
unit_config.name
|
121
125
|
end
|
122
|
-
end.compact
|
126
|
+
end.compact.uniq
|
123
127
|
end
|
124
|
-
# rubocop:enable Style/Next
|
125
128
|
|
126
|
-
def
|
129
|
+
def exec_on_needed_units_for(unit_names)
|
127
130
|
exec_on_units(unit_names) do |unit|
|
128
131
|
$logger.debug "Processing '#{unit.display_name}' unit"
|
129
132
|
yield(unit)
|
@@ -135,21 +138,21 @@ module Percheron
|
|
135
138
|
units(unit_names).each { |_, unit| yield(unit) }
|
136
139
|
end
|
137
140
|
|
138
|
-
def
|
141
|
+
def needed_units_for(unit_names)
|
139
142
|
list = []
|
140
143
|
unit_names = filter_unit_names(unit_names)
|
141
|
-
units =
|
142
|
-
units.each do |unit_name,
|
143
|
-
list +=
|
144
|
+
units = all_units_and_neededs(unit_names)
|
145
|
+
units.each do |unit_name, needed_unit_names|
|
146
|
+
list += needed_unit_names unless needed_unit_names.empty?
|
144
147
|
list << unit_name
|
145
148
|
end
|
146
149
|
list.uniq
|
147
150
|
end
|
148
151
|
|
149
|
-
def
|
152
|
+
def all_units_and_neededs(unit_names)
|
150
153
|
all_units = units
|
151
154
|
units = unit_names.each_with_object({}) do |unit_name, all|
|
152
|
-
all[unit_name] = all_units[unit_name].
|
155
|
+
all[unit_name] = all_units[unit_name].needed_unit_names
|
153
156
|
end
|
154
157
|
units.sort { |x, y| x[1].length <=> y[1].length } # FIXME
|
155
158
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Percheron
|
2
|
+
class Unit
|
3
|
+
module ImageHelper
|
4
|
+
def image_name
|
5
|
+
'%s:%s' % [ image_repo, image_version.to_s ] if image_repo && image_version
|
6
|
+
end
|
7
|
+
|
8
|
+
def image_repo
|
9
|
+
if !buildable?
|
10
|
+
unit_config.docker_image.split(':')[0]
|
11
|
+
elsif pseudo?
|
12
|
+
pseudo_full_name
|
13
|
+
else
|
14
|
+
full_name
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def image_version
|
19
|
+
if buildable?
|
20
|
+
unit_config.version
|
21
|
+
elsif !unit_config.docker_image.nil?
|
22
|
+
unit_config.docker_image.split(':')[1] || 'latest'
|
23
|
+
else
|
24
|
+
fail Errors::UnitInvalid, 'Cannot determine image version'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def image_exists?
|
29
|
+
image.nil? ? false : true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/percheron/unit.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
|
+
require 'percheron/unit/image_helper'
|
2
|
+
|
1
3
|
module Percheron
|
2
4
|
class Unit
|
3
5
|
|
4
6
|
extend Forwardable
|
5
7
|
extend ConfigDelegator
|
8
|
+
include Unit::ImageHelper
|
6
9
|
|
7
10
|
def_delegators :unit_config, :name, :pseudo_name, :docker_image
|
8
|
-
def_config_item_with_default :unit_config, [], :env, :ports, :volumes,
|
9
|
-
:
|
10
|
-
:post_start_scripts, :start_args, :dns
|
11
|
+
def_config_item_with_default :unit_config, [], :env, :ports, :volumes, :needed_unit_names,
|
12
|
+
:pre_build_scripts, :post_start_scripts, :start_args, :dns
|
11
13
|
def_config_item_with_default :unit_config, true, :startable
|
12
14
|
|
13
15
|
def initialize(config, stack, unit_name)
|
@@ -18,14 +20,14 @@ module Percheron
|
|
18
20
|
self
|
19
21
|
end
|
20
22
|
|
21
|
-
def
|
22
|
-
|
23
|
+
def needed_units
|
24
|
+
needed_unit_names.each_with_object({}) do |unit_name, all|
|
23
25
|
all[unit_name] = stack.units[unit_name]
|
24
26
|
end
|
25
27
|
end
|
26
28
|
|
27
|
-
def
|
28
|
-
|
29
|
+
def startable_needed_units
|
30
|
+
needed_units.select { |_, unit| unit.startable? }
|
29
31
|
end
|
30
32
|
|
31
33
|
def metastore_key
|
@@ -37,31 +39,19 @@ module Percheron
|
|
37
39
|
end
|
38
40
|
|
39
41
|
def hostname
|
40
|
-
unit_config.fetch('hostname',
|
41
|
-
end
|
42
|
-
|
43
|
-
def image_name
|
44
|
-
'%s:%s' % [ image_repo, image_version.to_s ] if image_repo && image_version
|
42
|
+
unit_config.fetch('hostname', full_name)
|
45
43
|
end
|
46
44
|
|
47
|
-
def
|
48
|
-
|
49
|
-
unit_config.
|
50
|
-
|
51
|
-
|
52
|
-
else
|
53
|
-
full_name
|
45
|
+
def restart_policy
|
46
|
+
@restart_policy ||= begin
|
47
|
+
name = unit_config.fetch('restart_policy', 'always')
|
48
|
+
max_retry_count = unit_config.fetch('restart_policy_retry_count', 0)
|
49
|
+
{ 'Name' => name, 'MaximumRetryCount' => max_retry_count }
|
54
50
|
end
|
55
51
|
end
|
56
52
|
|
57
|
-
def
|
58
|
-
|
59
|
-
unit_config.version
|
60
|
-
elsif !unit_config.docker_image.nil?
|
61
|
-
unit_config.docker_image.split(':')[1] || 'latest'
|
62
|
-
else
|
63
|
-
fail Errors::UnitInvalid, 'Cannot determine image version'
|
64
|
-
end
|
53
|
+
def privileged
|
54
|
+
unit_config.fetch('privileged', false)
|
65
55
|
end
|
66
56
|
|
67
57
|
def full_name
|
@@ -95,9 +85,7 @@ module Percheron
|
|
95
85
|
end
|
96
86
|
|
97
87
|
def links
|
98
|
-
|
99
|
-
'%s:%s' % [ unit.full_name, unit.full_name ]
|
100
|
-
end
|
88
|
+
startable_needed_units.map { |_, unit| '%s:%s' % [ unit.full_name, unit.full_name ] }
|
101
89
|
end
|
102
90
|
|
103
91
|
def container
|
@@ -141,10 +129,6 @@ module Percheron
|
|
141
129
|
!info.empty?
|
142
130
|
end
|
143
131
|
|
144
|
-
def image_exists?
|
145
|
-
image.nil? ? false : true
|
146
|
-
end
|
147
|
-
|
148
132
|
def buildable?
|
149
133
|
!dockerfile.nil? && unit_config.docker_image.nil?
|
150
134
|
end
|
@@ -178,6 +162,5 @@ module Percheron
|
|
178
162
|
def info
|
179
163
|
Hashie::Mash.new(container.info)
|
180
164
|
end
|
181
|
-
|
182
165
|
end
|
183
166
|
end
|
data/lib/percheron/version.rb
CHANGED
data/lib/percheron.rb
CHANGED
data/percheron.gemspec
CHANGED
@@ -36,7 +36,7 @@ Gem::Specification.new do |spec|
|
|
36
36
|
spec.add_development_dependency 'pry-byebug', '~> 3.2.0'
|
37
37
|
spec.add_development_dependency 'rake', '~> 10.4.0'
|
38
38
|
spec.add_development_dependency 'rspec', '~> 3.3.0'
|
39
|
-
spec.add_development_dependency 'rubocop', '~> 0.
|
39
|
+
spec.add_development_dependency 'rubocop', '~> 0.33.0'
|
40
40
|
spec.add_development_dependency 'simplecov', '~> 0.10.0'
|
41
41
|
spec.add_development_dependency 'timecop', '~> 0.8.0'
|
42
42
|
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.8.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-08-
|
11
|
+
date: 2015-08-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: clamp
|
@@ -254,14 +254,14 @@ dependencies:
|
|
254
254
|
requirements:
|
255
255
|
- - "~>"
|
256
256
|
- !ruby/object:Gem::Version
|
257
|
-
version: 0.
|
257
|
+
version: 0.33.0
|
258
258
|
type: :development
|
259
259
|
prerelease: false
|
260
260
|
version_requirements: !ruby/object:Gem::Requirement
|
261
261
|
requirements:
|
262
262
|
- - "~>"
|
263
263
|
- !ruby/object:Gem::Version
|
264
|
-
version: 0.
|
264
|
+
version: 0.33.0
|
265
265
|
- !ruby/object:Gem::Dependency
|
266
266
|
name: simplecov
|
267
267
|
requirement: !ruby/object:Gem::Requirement
|
@@ -322,7 +322,6 @@ files:
|
|
322
322
|
- lib/percheron/actions/exec_local.rb
|
323
323
|
- lib/percheron/actions/logs.rb
|
324
324
|
- lib/percheron/actions/purge.rb
|
325
|
-
- lib/percheron/actions/recreate.rb
|
326
325
|
- lib/percheron/actions/restart.rb
|
327
326
|
- lib/percheron/actions/shell.rb
|
328
327
|
- lib/percheron/actions/start.rb
|
@@ -337,7 +336,6 @@ files:
|
|
337
336
|
- lib/percheron/commands/logs.rb
|
338
337
|
- lib/percheron/commands/main.rb
|
339
338
|
- lib/percheron/commands/purge.rb
|
340
|
-
- lib/percheron/commands/recreate.rb
|
341
339
|
- lib/percheron/commands/restart.rb
|
342
340
|
- lib/percheron/commands/shell.rb
|
343
341
|
- lib/percheron/commands/start.rb
|
@@ -358,6 +356,7 @@ files:
|
|
358
356
|
- lib/percheron/oh_dear.rb
|
359
357
|
- lib/percheron/stack.rb
|
360
358
|
- lib/percheron/unit.rb
|
359
|
+
- lib/percheron/unit/image_helper.rb
|
361
360
|
- lib/percheron/validators.rb
|
362
361
|
- lib/percheron/validators/config.rb
|
363
362
|
- lib/percheron/validators/docker_client.rb
|
@@ -1,51 +0,0 @@
|
|
1
|
-
module Percheron
|
2
|
-
module Actions
|
3
|
-
class Recreate
|
4
|
-
|
5
|
-
include Base
|
6
|
-
|
7
|
-
def initialize(unit, start: false, force: false)
|
8
|
-
@unit = unit
|
9
|
-
@start = start
|
10
|
-
@force = force
|
11
|
-
end
|
12
|
-
|
13
|
-
def execute!
|
14
|
-
results = []
|
15
|
-
if recreate? || force?
|
16
|
-
results << recreate!
|
17
|
-
results << start!
|
18
|
-
else
|
19
|
-
inform!
|
20
|
-
end
|
21
|
-
results.compact.empty? ? nil : unit
|
22
|
-
end
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
attr_reader :unit, :start, :force
|
27
|
-
alias_method :start?, :start
|
28
|
-
alias_method :force?, :force
|
29
|
-
|
30
|
-
def recreate?
|
31
|
-
!unit.versions_match? || !unit.dockerfile_md5s_match?
|
32
|
-
end
|
33
|
-
|
34
|
-
def inform!
|
35
|
-
return nil unless unit.dockerfile_md5s_match?
|
36
|
-
$logger.info "Unit '#{unit.display_name}' - No Dockerfile changes or version bump"
|
37
|
-
end
|
38
|
-
|
39
|
-
def recreate!
|
40
|
-
$logger.debug "Unit '#{unit.display_name}' exists but will be recreated"
|
41
|
-
Purge.new(unit).execute!
|
42
|
-
Create.new(unit).execute!
|
43
|
-
end
|
44
|
-
|
45
|
-
def start!
|
46
|
-
Start.new(unit).execute! if start?
|
47
|
-
end
|
48
|
-
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
module Percheron
|
2
|
-
module Commands
|
3
|
-
class Recreate < Abstract
|
4
|
-
|
5
|
-
default_create_parameters!
|
6
|
-
option([ '-f', '--force' ], :flag, 'Force purge and create', default: false)
|
7
|
-
|
8
|
-
def execute
|
9
|
-
super
|
10
|
-
stack.recreate!(unit_names: unit_names, start: start?, force: force?)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|