percheron 0.7.16 → 0.8.0
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 +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
|