dapp 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NTM1NTkwNWNjMzM0YTkzYTdlOGMzODY4MzE4ZGQ5YWZmNjI0YmU5Zg==
4
+ YzZiYzcxYjE1NWZlOGFhNTkzNzYzYTU5OTBhYmFmMTcxNjJkOGE5YQ==
5
5
  data.tar.gz: !binary |-
6
- YjM5ODYyYzIzNDA3YjkyODFkYThjYjE2NTFhNDA4MGQxM2IyZGE2Mg==
6
+ NWM2YTA4OTY5MTRhZmU2YzUxMDhmNWQwMmRmNmIzY2JjOWE0MTI0Ng==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- OThjNmU0YmUyODZlODdkNzI2YjdiM2MyZDA4YmZkOWY2NTdmM2Y4MGJkYWM1
10
- MTliMzkyMjcwMThiMGMzNTE2MGQyMGI0NGMyMTNlMDdkM2M5NDMzYjcxZTc0
11
- YzM3YmMzZTkyNGYwZTM4YmJjMjY5YmFkN2U3YmVmMTgwODA5ZWY=
9
+ MDljYWUxMTk5MDM2ZGE3YmQ4MWUzMGRlNTU4ZTMwYmQ1OGRkOTQzMDBkMDU2
10
+ YTkzNTgzNmFmMGY3YjcxMjA5MDg4Y2I0OGE1MmZhMDIwOWRkM2FhMWM4Mzhm
11
+ Nzc1ZTFmNzIxNWM1NWY5MWNhNTQzZjQzZmU5NDg4YTYyNWZkY2I=
12
12
  data.tar.gz: !binary |-
13
- OWRiZGIzNzY0MTQzYzk3OTJlMDYxNDA4ZjI2OWEwZGQzNDQ2NTQ3NjQ4MGUx
14
- N2Y4NTVmY2UyNTNhMGUzNmUwMTI1Zjg3ODJjZDhlYmIwZDIyZDgxZTFiZmRm
15
- YWUwNGU0ZmY1MzJlNmU2ZDNhYmRmYTg1ZWFmODU1ZTYxMWFjZDQ=
13
+ ZGIzNTcyYjRhMjM4MTIxYjJiYWU4ODU5NDYzYjQxZjhlZjA3MGI4OGNlMzVj
14
+ Y2U0NTdhOThiMGJmMTVmODYyYTUzMWQ4NDkzNzZhYzgwYTBlMTc3MWU0NGU5
15
+ MDg5ZDQxYjg0Y2YxZWIxZDM0MTNkMWE0MDY4ZjAyYTE5MGM5NTg=
data/bin/dapp CHANGED
@@ -10,7 +10,7 @@ begin
10
10
  rescue Dapp::Error::Shellout => e
11
11
  $stderr.puts(Dapp::Helper::NetStatus.message(e))
12
12
  exit 1
13
- rescue Dapp::Error::Base => e
13
+ rescue Dapp::Error::Base, NetStatus::Exception => e
14
14
  $stderr.puts(Dapp::Helper::Paint.paint_string(Dapp::Helper::NetStatus.message(e), :warning))
15
15
  exit 1
16
16
  rescue Interrupt => _e
@@ -2,10 +2,14 @@ en:
2
2
  common:
3
3
  image:
4
4
  signature: "signature: %{signature}"
5
- info: "date: %{date}\nsize: %{size} MB"
5
+ info:
6
+ date: "date: %{value}"
7
+ size: "size: %{value} MB"
8
+ difference: "difference: %{value} MB"
6
9
  commands: "commands:"
7
10
  process:
8
11
  artifact_copy: "copying artifact '%{name}'"
12
+ artifact_building: "building artifact '%{name}'"
9
13
  git_artifact_loading: 'loading git_artifact'
10
14
  git_artifact_clone: "cloning remote git_artifact '%{name}'"
11
15
  git_artifact_fetch: "fetching remote git_artifact '%{name}'"
@@ -22,6 +26,7 @@ en:
22
26
  default: '[FAILED]'
23
27
  state:
24
28
  using_cache: '[USING CACHE]'
29
+ not_present: '[NOT PRESENT]'
25
30
  build: '[BUILD]'
26
31
  push: '[PUSH]'
27
32
  introspect:
@@ -1,6 +1,6 @@
1
1
  en:
2
2
  net_status:
3
- missing_translation: "Missing translation for code: '%{code}'."
3
+ missing_translation: "Missing translation for code: '%{code}'!"
4
4
  shellout:
5
5
  shell_command_failed: ">>> START STREAM\n%{stream}\n>>> END STREAM"
6
6
  application:
@@ -23,5 +23,7 @@ en:
23
23
  builder_type_conflict: 'Conflict between builder types!'
24
24
  builder_type_unsupported: "Defined unsupported builder type `%{type}`!"
25
25
  docker_from_not_defined: "Docker `from` not defined!"
26
- artifact_unexpected_attribute: "Artifact doesn't have attribute '%{attr}'!"
27
- git_artifact_unexpected_attribute: "'%{type}' git artifact doesn't have attribute '%{attr}'!"
26
+ artifact_unexpected_attribute: "Artifact doesn't has attribute '%{attr}'!"
27
+ stage_artifact_not_associated: "Artifact not associated with any stage!"
28
+ stage_artifact_incorrect_associated_value: "Artifact option '%{option}' has incorrect value '%{value}'!"
29
+ git_artifact_unexpected_attribute: "'%{type}' git artifact doesn't has attribute '%{attr}'!"
@@ -31,9 +31,9 @@ require 'dapp/cli/build'
31
31
  require 'dapp/cli/push'
32
32
  require 'dapp/cli/smartpush'
33
33
  require 'dapp/cli/list'
34
- require 'dapp/cli/flush'
35
- require 'dapp/cli/flush/stages'
36
- require 'dapp/cli/flush/metadata'
34
+ require 'dapp/cli/stages'
35
+ require 'dapp/cli/stages/flush'
36
+ require 'dapp/cli/stages/cleanup'
37
37
  require 'dapp/cli/run'
38
38
  require 'dapp/filelock'
39
39
  require 'dapp/config/application'
@@ -48,6 +48,8 @@ require 'dapp/builder/chef'
48
48
  require 'dapp/builder/chef/cookbook_metadata'
49
49
  require 'dapp/builder/chef/berksfile'
50
50
  require 'dapp/builder/shell'
51
+ require 'dapp/build/stage/mod/artifact'
52
+ require 'dapp/build/stage/mod/logging'
51
53
  require 'dapp/build/stage/base'
52
54
  require 'dapp/build/stage/source_base'
53
55
  require 'dapp/build/stage/from'
@@ -29,11 +29,8 @@ module Dapp
29
29
  end
30
30
 
31
31
  def build!
32
- log_step(config._name)
33
- with_log_indent do
34
- last_stage.build!
35
- last_stage.save_in_cache!
36
- end
32
+ last_stage.build!
33
+ last_stage.save_in_cache!
37
34
  ensure
38
35
  FileUtils.rm_rf(tmp_path)
39
36
  end
@@ -71,10 +68,6 @@ module Dapp
71
68
  @builder ||= Builder.const_get(config._builder.capitalize).new(self)
72
69
  end
73
70
 
74
- def meta_options
75
- { cli_options: cli_options, ignore_git_fetch: ignore_git_fetch }
76
- end
77
-
78
71
  protected
79
72
 
80
73
  attr_reader :last_stage
@@ -5,6 +5,8 @@ module Dapp
5
5
  class Base
6
6
  include Helper::Sha256
7
7
  include Helper::Trivia
8
+ include Mod::Artifact
9
+ include Mod::Logging
8
10
 
9
11
  attr_accessor :prev_stage, :next_stage
10
12
  attr_reader :application
@@ -16,28 +18,14 @@ module Dapp
16
18
  @next_stage.prev_stage = self
17
19
  end
18
20
 
19
- # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
20
21
  def build!
21
22
  return if should_be_skipped?
22
23
  prev_stage.build! if prev_stage
23
- begin
24
- if image.tagged?
25
- application.log_state(name, state: application.t(code: 'state.using_cache'))
26
- elsif application.dry_run?
27
- application.log_state(name, state: application.t(code: 'state.build'), styles: { status: :success })
28
- else
29
- application.log_process(name, process: application.t(code: 'status.process.building'), short: should_be_not_detailed?) do
30
- image_build!
31
- end
32
- end
33
- ensure
34
- log_build
35
- end
24
+ image_build
36
25
  raise Exception::IntrospectImage,
37
26
  message: application.t(code: 'introspect.stage', data: { name: name }),
38
27
  data: { built_id: image.built_id, options: image.send(:prepared_options) } if should_be_introspected?
39
28
  end
40
- # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
41
29
 
42
30
  def save_in_cache!
43
31
  return if image.tagged?
@@ -53,6 +41,7 @@ module Dapp
53
41
  @image ||= begin
54
42
  Image::Stage.new(name: image_name, from: from_image).tap do |image|
55
43
  image.add_volume "#{application.tmp_path}:#{application.container_tmp_path}"
44
+ image.add_change_label dapp: application.config._basename
56
45
  before_artifacts.each { |artifact| apply_artifact(artifact, image) }
57
46
  yield image if block_given?
58
47
  after_artifacts.each { |artifact| apply_artifact(artifact, image) }
@@ -66,19 +55,25 @@ module Dapp
66
55
  class_to_lowercase.to_sym
67
56
  end
68
57
 
69
- def should_be_not_detailed?
70
- image.send(:bash_commands).empty?
71
- end
72
-
73
- def should_be_skipped?
74
- image.tagged? && !application.log_verbose? && application.cli_options[:introspect_stage].nil?
75
- end
76
-
77
- def should_be_introspected?
78
- application.cli_options[:introspect_stage] == name && !application.dry_run? && !application.is_artifact
58
+ # rubocop:disable Metrics/AbcSize
59
+ def image_build
60
+ if image.tagged?
61
+ application.log_state(name, state: application.t(code: 'state.using_cache'))
62
+ elsif should_be_not_present?
63
+ application.log_state(name, state: application.t(code: 'state.not_present'))
64
+ elsif application.dry_run?
65
+ application.log_state(name, state: application.t(code: 'state.build'), styles: { status: :success })
66
+ else
67
+ application.log_process(name, process: application.t(code: 'status.process.building'), short: should_be_not_detailed?) do
68
+ image_do_build
69
+ end
70
+ end
71
+ ensure
72
+ log_build
79
73
  end
74
+ # rubocop:enable Metrics/AbcSize
80
75
 
81
- def image_build!
76
+ def image_do_build
82
77
  image.build!(log_verbose: application.log_verbose?,
83
78
  log_time: application.log_time?,
84
79
  introspect_error: application.cli_options[:introspect_error],
@@ -92,97 +87,8 @@ module Dapp
92
87
  end
93
88
 
94
89
  def image_name
95
- "dapp:#{signature}"
96
- end
97
-
98
- def image_info
99
- date, size = image.info
100
- _date, from_size = from_image.info
101
- [date, (from_size.to_f - size.to_f).abs]
102
- end
103
-
104
- def format_image_info
105
- date, size = image_info
106
- application.t(code: 'image.info', data: { date: Time.parse(date).localtime, size: size.to_f.round(2) })
107
- end
108
-
109
- # rubocop:disable Metrics/AbcSize
110
- def log_build
111
- application.with_log_indent do
112
- application.log_info application.t(code: 'image.signature', data: { signature: image_name })
113
- application.log_info format_image_info if image.tagged?
114
- unless (bash_commands = image.send(:bash_commands)).empty?
115
- application.log_info application.t(code: 'image.commands')
116
- application.with_log_indent { application.log_info bash_commands.join("\n") }
117
- end
118
- end if application.log? && application.log_verbose?
119
- end
120
- # rubocop:enable Metrics/AbcSize
121
-
122
- def before_artifacts
123
- @before_artifacts ||= do_artifacts(application.config._artifact.select { |artifact| artifact._before == name })
124
- end
125
-
126
- def after_artifacts
127
- @after_artifacts ||= do_artifacts(application.config._artifact.select { |artifact| artifact._after == name })
128
- end
129
-
130
- def do_artifacts(artifacts)
131
- artifacts.map do |artifact|
132
- {
133
- name: artifact._config._name,
134
- options: artifact._artifact_options,
135
- app: Application.new(config: artifact._config, is_artifact: true, **application.meta_options).tap(&:build!)
136
- }
137
- end
138
- end
139
-
140
- def artifacts_signatures
141
- (before_artifacts + after_artifacts).map { |artifact| hashsum [artifact[:app].signature, artifact[:options]] }
142
- end
143
-
144
- def apply_artifact(artifact, image)
145
- return if application.dry_run?
146
-
147
- artifact_name = artifact[:name]
148
- app = artifact[:app]
149
- cwd = artifact[:options][:cwd]
150
- paths = artifact[:options][:paths]
151
- owner = artifact[:options][:owner]
152
- group = artifact[:options][:group]
153
- where_to_add = artifact[:options][:where_to_add]
154
-
155
- docker_options = ['--rm',
156
- "--volume #{application.tmp_path('artifact', artifact_name)}:#{app.container_tmp_path(artifact_name)}",
157
- '--entrypoint /bin/sh']
158
- commands = safe_cp(where_to_add, app.container_tmp_path(artifact_name), Process.uid, Process.gid)
159
- application.log_secondary_process(application.t(code: 'process.artifact_copy', data: { name: artifact_name }), short: true) do
160
- app.run(docker_options, Array(application.shellout_pack(commands)))
161
- end
162
-
163
- commands = safe_cp(application.container_tmp_path('artifact', artifact_name), where_to_add, owner, group, cwd, paths)
164
- image.add_commands commands
165
- end
166
-
167
- # rubocop:disable Metrics/ParameterLists
168
- def safe_cp(from, to, owner, group, cwd = '', paths = [])
169
- credentials = ''
170
- credentials += "-o #{owner} " if owner
171
- credentials += "-g #{group} " if group
172
-
173
- commands = []
174
- commands << ['install', credentials, '-d', to].join(' ')
175
-
176
- copy_files = lambda do |from_, cwd_, path_ = ''|
177
- "find #{File.join(from_, cwd_, path_)} -type f -exec bash -ec 'install -D #{credentials} {} " \
178
- "#{File.join(to, "$(echo {} | sed -e \"s/#{File.join(from_, cwd_).gsub('/', '\\/')}//g\")")}' \\;"
179
- end
180
-
181
- commands.concat(paths.empty? ? Array(copy_files.call(from, cwd)) : paths.map { |path| copy_files.call(from, cwd, path) })
182
- commands << "find #{to} -type d -exec bash -ec 'install -d #{credentials} {}' \\;"
183
- commands.join(' && ')
90
+ "#{application.config._basename}-dappstage:#{signature}"
184
91
  end
185
- # rubocop:enable Metrics/ParameterLists
186
92
  end # Base
187
93
  end # Stage
188
94
  end # Build
@@ -17,7 +17,7 @@ module Dapp
17
17
 
18
18
  protected
19
19
 
20
- def image_build!
20
+ def image_do_build
21
21
  from_image.pull!(log_time: application.log_time?)
22
22
  super
23
23
  end
@@ -31,10 +31,6 @@ module Dapp
31
31
  def from_image
32
32
  @from_image ||= Image::Stage.new(name: from_image_name)
33
33
  end
34
-
35
- def image_info
36
- image.info
37
- end
38
34
  end # Prepare
39
35
  end # Stage
40
36
  end # Build
@@ -0,0 +1,92 @@
1
+ module Dapp
2
+ module Build
3
+ module Stage
4
+ # Mod
5
+ module Mod
6
+ # Artifact
7
+ module Artifact
8
+ def before_artifacts
9
+ @before_artifacts ||= do_artifacts(application.config._artifact.select { |artifact| artifact._before == name })
10
+ end
11
+
12
+ def after_artifacts
13
+ @after_artifacts ||= do_artifacts(application.config._artifact.select { |artifact| artifact._after == name })
14
+ end
15
+
16
+ def do_artifacts(artifacts)
17
+ verbose = application.log_verbose?
18
+ artifacts.map do |artifact|
19
+ process = application.t(code: 'process.artifact_building', data: { name: artifact._config._name })
20
+ application.log_secondary_process(process, short: !verbose) do
21
+ application.with_log_indent do
22
+ {
23
+ name: artifact._config._name,
24
+ options: artifact._artifact_options,
25
+ app: Application.new(artifact_app_options(artifact, verbose)).tap(&:build!)
26
+ }
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ def artifact_app_options(artifact, verbose)
33
+ {
34
+ config: artifact._config,
35
+ cli_options: application.cli_options.merge(log_quiet: !verbose),
36
+ ignore_git_fetch: application.ignore_git_fetch,
37
+ is_artifact: true
38
+ }
39
+ end
40
+
41
+ def artifacts_signatures
42
+ (before_artifacts + after_artifacts).map { |artifact| hashsum [artifact[:app].signature, artifact[:options]] }
43
+ end
44
+
45
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
46
+ def apply_artifact(artifact, image)
47
+ return if application.dry_run?
48
+
49
+ artifact_name = artifact[:name]
50
+ app = artifact[:app]
51
+ cwd = artifact[:options][:cwd]
52
+ paths = artifact[:options][:paths]
53
+ owner = artifact[:options][:owner]
54
+ group = artifact[:options][:group]
55
+ where_to_add = artifact[:options][:where_to_add]
56
+
57
+ docker_options = ['--rm',
58
+ "--volume #{application.tmp_path('artifact', artifact_name)}:#{app.container_tmp_path(artifact_name)}",
59
+ '--entrypoint /bin/sh']
60
+ commands = safe_cp(where_to_add, app.container_tmp_path(artifact_name), Process.uid, Process.gid)
61
+ application.log_secondary_process(application.t(code: 'process.artifact_copy', data: { name: artifact_name }), short: true) do
62
+ app.run(docker_options, Array(application.shellout_pack(commands)))
63
+ end
64
+
65
+ commands = safe_cp(application.container_tmp_path('artifact', artifact_name), where_to_add, owner, group, cwd, paths)
66
+ image.add_commands commands
67
+ end
68
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
69
+
70
+ # rubocop:disable Metrics/ParameterLists
71
+ def safe_cp(from, to, owner, group, cwd = '', paths = [])
72
+ credentials = ''
73
+ credentials += "-o #{owner} " if owner
74
+ credentials += "-g #{group} " if group
75
+
76
+ copy_files = lambda do |from_, cwd_, path_ = ''|
77
+ "find #{File.join(from_, cwd_, path_)} -type f -exec bash -ec 'install -D #{credentials} {} " \
78
+ "#{File.join(to, "$(echo {} | sed -e \"s/#{File.join(from_, cwd_).gsub('/', '\\/')}//g\")")}' \\;"
79
+ end
80
+
81
+ commands = []
82
+ commands << ['install', credentials, '-d', to].join(' ')
83
+ commands.concat(paths.empty? ? Array(copy_files.call(from, cwd)) : paths.map { |path| copy_files.call(from, cwd, path) })
84
+ commands << "find #{to} -type d -exec bash -ec 'install -d #{credentials} {}' \\;"
85
+ commands.join(' && ')
86
+ end
87
+ # rubocop:enable Metrics/ParameterLists
88
+ end
89
+ end # Mod
90
+ end # Stage
91
+ end # Build
92
+ end # Dapp
@@ -0,0 +1,64 @@
1
+ module Dapp
2
+ module Build
3
+ module Stage
4
+ # Mod
5
+ module Mod
6
+ # Logging
7
+ module Logging
8
+ def log_build
9
+ application.with_log_indent do
10
+ application.log_info application.t(code: 'image.signature', data: { signature: image_name })
11
+ log_image_info
12
+ log_image_commands
13
+ end if application.log? && application.log_verbose?
14
+ end
15
+
16
+ def log_image_commands
17
+ return if (bash_commands = image.send(:bash_commands)).empty?
18
+ application.log_info application.t(code: 'image.commands')
19
+ application.with_log_indent { application.log_info bash_commands.join("\n") }
20
+ end
21
+
22
+ def log_image_info
23
+ return unless image.tagged?
24
+ date, size = image_info
25
+ application.log_info application.t(code: 'image.info.date', data: { value: date })
26
+ size_code = size_difference? ? 'image.info.difference' : 'image.info.size'
27
+ application.log_info application.t(code: size_code, data: { value: size })
28
+ end
29
+
30
+ def image_info
31
+ date, size = image.info
32
+ if size_difference?
33
+ _date, from_size = from_image.info
34
+ size = size.to_f - from_size.to_f
35
+ end
36
+
37
+ [Time.parse(date).localtime, size.to_f.round(2)]
38
+ end
39
+
40
+ def size_difference?
41
+ from_image.tagged? && !prev_stage.nil?
42
+ end
43
+
44
+ def should_be_skipped?
45
+ image.tagged? && !application.log_verbose? && application.cli_options[:introspect_stage].nil?
46
+ end
47
+
48
+ def should_be_not_present?
49
+ return false if next_stage.nil?
50
+ next_stage.image.tagged? || next_stage.should_be_not_present?
51
+ end
52
+
53
+ def should_be_not_detailed?
54
+ image.send(:bash_commands).empty?
55
+ end
56
+
57
+ def should_be_introspected?
58
+ application.cli_options[:introspect_stage] == name && !application.dry_run? && !application.is_artifact
59
+ end
60
+ end
61
+ end # Mod
62
+ end # Stage
63
+ end # Build
64
+ end # Dapp
@@ -65,20 +65,19 @@ module Dapp
65
65
  @cookbook_metadata ||= CookbookMetadata.new(cookbook_metadata_path)
66
66
  end
67
67
 
68
-
69
68
  def berksfile_lock_checksum
70
69
  application.hashsum berksfile_lock_path.read if berksfile_lock_path.exist?
71
70
  end
72
71
 
73
72
  def local_cookbook_paths_for_checksum
74
73
  @local_cookbook_paths_for_checksum ||= berksfile
75
- .local_cookbooks
76
- .values
77
- .map { |cookbook| cookbook[:path] }
78
- .product(LOCAL_COOKBOOK_CHECKSUM_PATTERNS)
79
- .map { |cb, dir| Dir[cb.join(dir)] }
80
- .flatten
81
- .map(&Pathname.method(:new))
74
+ .local_cookbooks
75
+ .values
76
+ .map { |cookbook| cookbook[:path] }
77
+ .product(LOCAL_COOKBOOK_CHECKSUM_PATTERNS)
78
+ .map { |cb, dir| Dir[cb.join(dir)] }
79
+ .flatten
80
+ .map(&Pathname.method(:new))
82
81
  end
83
82
 
84
83
  def stage_cookbooks_paths_for_checksum(stage)
@@ -95,14 +94,14 @@ module Dapp
95
94
  stage_cookbooks_checksum_path(stage).read.strip
96
95
  else
97
96
  checksum = if stage == :chef_cookbooks
98
- cookbooks_checksum
99
- else
100
- application.hashsum [
101
- _paths_checksum(stage_cookbooks_paths_for_checksum(stage)),
102
- *application.config._chef._modules,
103
- stage == :infra_install ? chefdk_image : nil
104
- ].compact
105
- end
97
+ cookbooks_checksum
98
+ else
99
+ application.hashsum [
100
+ _paths_checksum(stage_cookbooks_paths_for_checksum(stage)),
101
+ *application.config._chef._modules,
102
+ stage == :infra_install ? chefdk_image : nil
103
+ ].compact
104
+ end
106
105
 
107
106
  stage_cookbooks_checksum_path(stage).write "#{checksum}\n"
108
107
  checksum
@@ -117,7 +116,6 @@ module Dapp
117
116
  ]
118
117
  end
119
118
 
120
-
121
119
  def chefdk_image
122
120
  DEFAULT_CHEFDK_IMAGE # TODO: config, DSL, DEFAULT_CHEFDK_IMAGE
123
121
  end
@@ -143,7 +141,6 @@ module Dapp
143
141
  end
144
142
  end
145
143
 
146
-
147
144
  # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
148
145
  def install_cookbooks
149
146
  volumes_from = chefdk_container
@@ -187,7 +184,7 @@ module Dapp
187
184
  # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
188
185
 
189
186
  def _cookbooks_vendor_path
190
- application.metadata_path("cookbooks.#{cookbooks_checksum}")
187
+ application.tmp_path(application.config._name, "cookbooks.#{cookbooks_checksum}")
191
188
  end
192
189
 
193
190
  def cookbooks_vendor_path(*path)
@@ -196,7 +193,6 @@ module Dapp
196
193
  end.join(*path)
197
194
  end
198
195
 
199
-
200
196
  # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
201
197
  def install_stage_cookbooks(stage)
202
198
  @install_stage_cookbooks ||= {}
@@ -204,36 +200,35 @@ module Dapp
204
200
  common_paths = proc do |cookbook_path|
205
201
  [['metadata.json', 'metadata.json'],
206
202
  ["files/#{stage}", 'files/default'],
207
- ["templates/#{stage}", 'templates/default']
208
- ].select { |from, _| cookbook_path.join(from).exist? }
203
+ ["templates/#{stage}", 'templates/default']].select { |from, _| cookbook_path.join(from).exist? }
209
204
  end
210
205
 
211
206
  install_paths = Dir[cookbooks_vendor_path('*')]
212
- .map(&Pathname.method(:new))
213
- .map { |cookbook_path|
214
- cookbook_name = File.basename cookbook_path
215
- is_project = (cookbook_name == project_name)
216
- is_mdapp = cookbook_name.start_with? 'mdapp-'
217
- mdapp_enabled = is_mdapp && application.config._chef._modules.include?(cookbook_name)
218
-
219
- paths = if is_project
220
- recipe_paths = application.config._chef._recipes
221
- .map { |recipe| ["recipes/#{stage}/#{recipe}.rb", "recipes/#{recipe}.rb"] }
222
- .select { |from, _| cookbook_path.join(from).exist? }
223
-
224
- (recipe_paths + common_paths[cookbook_path]) if recipe_paths.any?
225
- elsif is_mdapp and mdapp_enabled
226
- recipe_path = "recipes/#{stage}.rb"
227
- if cookbook_path.join(recipe_path).exist?
228
- [[recipe_path, recipe_path]] + common_paths[cookbook_path]
229
- end
230
- else
231
- [['.', '.']]
232
- end
233
-
234
- [cookbook_path, paths] if paths and paths.any?
235
- }
236
- .compact
207
+ .map(&Pathname.method(:new))
208
+ .map do |cookbook_path|
209
+ cookbook_name = File.basename cookbook_path
210
+ is_project = (cookbook_name == project_name)
211
+ is_mdapp = cookbook_name.start_with? 'mdapp-'
212
+ mdapp_enabled = is_mdapp && application.config._chef._modules.include?(cookbook_name)
213
+
214
+ paths = if is_project
215
+ recipe_paths = application.config._chef._recipes
216
+ .map { |recipe| ["recipes/#{stage}/#{recipe}.rb", "recipes/#{recipe}.rb"] }
217
+ .select { |from, _| cookbook_path.join(from).exist? }
218
+
219
+ (recipe_paths + common_paths[cookbook_path]) if recipe_paths.any?
220
+ elsif is_mdapp && mdapp_enabled
221
+ recipe_path = "recipes/#{stage}.rb"
222
+ if cookbook_path.join(recipe_path).exist?
223
+ [[recipe_path, recipe_path]] + common_paths[cookbook_path]
224
+ end
225
+ else
226
+ [['.', '.']]
227
+ end
228
+
229
+ [cookbook_path, paths] if paths && paths.any?
230
+ end
231
+ .compact
237
232
 
238
233
  stage_cookbooks_path(stage).mkpath
239
234
  install_paths.each do |cookbook_path, paths|
@@ -279,7 +274,6 @@ module Dapp
279
274
  stage_tmp_path(stage, 'cookbooks', *path)
280
275
  end
281
276
 
282
-
283
277
  def install_chef_solo_stage_config(stage)
284
278
  @install_chef_solo_stage_config ||= {}
285
279
  @install_chef_solo_stage_config[stage] ||= true.tap do
@@ -295,7 +289,6 @@ module Dapp
295
289
  container_stage_tmp_path(stage, 'config.rb', *path)
296
290
  end
297
291
 
298
-
299
292
  def stage_tmp_path(stage, *path)
300
293
  application.tmp_path(application.config._name, stage).join(*path)
301
294
  end
@@ -7,7 +7,7 @@ module Dapp
7
7
  include Mixlib::CLI
8
8
  include Helper::Trivia
9
9
 
10
- SUBCOMMANDS = %w(build smartpush push list run flush).freeze
10
+ SUBCOMMANDS = %w(build smartpush push list run stages).freeze
11
11
 
12
12
  banner <<BANNER.freeze
13
13
  Usage: dapp [options] sub-command [sub-command options]
@@ -19,7 +19,7 @@ dapp push [options] [PATTERN] REPO
19
19
  dapp smartpush [options] [PATTERN ...] REPOPREFIX
20
20
  dapp list [options] [PATTERN ...]
21
21
  dapp run [options] [PATTERN] [DOCKER ARGS]
22
- dapp flush
22
+ dapp stages
23
23
 
24
24
  Options:
25
25
  BANNER
@@ -3,16 +3,16 @@ require 'mixlib/cli'
3
3
  module Dapp
4
4
  class CLI
5
5
  # CLI flush subcommand
6
- class Flush < CLI
7
- SUBCOMMANDS = %w(metadata stages).freeze
6
+ class Stages < CLI
7
+ SUBCOMMANDS = %w(flush cleanup).freeze
8
8
 
9
9
  banner <<BANNER.freeze
10
10
  Version: #{Dapp::VERSION}
11
11
 
12
12
  Available subcommands: (for details, dapp SUB-COMMAND --help)
13
13
 
14
- dapp flush metadata
15
- dapp flush stages
14
+ dapp stages flush
15
+ dapp stages cleanup
16
16
  BANNER
17
17
  end
18
18
  end
@@ -2,23 +2,19 @@ require 'mixlib/cli'
2
2
 
3
3
  module Dapp
4
4
  class CLI
5
- class Flush
6
- # Flush metadata subcommand
7
- class Metadata < Base
5
+ class Stages
6
+ # Flush stages subcommand
7
+ class Cleanup < Base
8
8
  banner <<BANNER.freeze
9
9
  Version: #{Dapp::VERSION}
10
10
 
11
11
  Usage:
12
- dapp flush metadata
12
+ dapp stages cleanup
13
13
  Options:
14
14
  BANNER
15
- option :metadata_dir,
16
- long: '--metadata-dir PATH',
17
- description: 'Metadata directory'
18
-
19
15
  def run(argv = ARGV)
20
16
  self.class.parse_options(self, argv)
21
- Controller.new(cli_options: config, patterns: cli_arguments).flush_metadata
17
+ Controller.new(cli_options: config, patterns: cli_arguments).stages_cleanup
22
18
  end
23
19
  end
24
20
  end
@@ -2,20 +2,19 @@ require 'mixlib/cli'
2
2
 
3
3
  module Dapp
4
4
  class CLI
5
- class Flush
5
+ class Stages
6
6
  # Flush stages subcommand
7
- class Stages < Flush
7
+ class Flush < Base
8
8
  banner <<BANNER.freeze
9
9
  Version: #{Dapp::VERSION}
10
10
 
11
11
  Usage:
12
- dapp flush stages
12
+ dapp stages flush
13
13
  Options:
14
14
  BANNER
15
-
16
15
  def run(argv = ARGV)
17
16
  self.class.parse_options(self, argv)
18
- Controller.flush_stages
17
+ Controller.new(cli_options: config, patterns: cli_arguments).stages_flush
19
18
  end
20
19
  end
21
20
  end
@@ -2,9 +2,9 @@ module Dapp
2
2
  module Config
3
3
  # Application
4
4
  class Application
5
- attr_reader :_name
6
5
  attr_reader :_builder
7
6
  attr_reader :_home_path
7
+ attr_reader :_basename
8
8
  attr_reader :_docker
9
9
  attr_reader :_git_artifact
10
10
  attr_reader :_artifact
@@ -70,6 +70,10 @@ module Dapp
70
70
  @_builder = type
71
71
  end
72
72
 
73
+ def _name
74
+ @_name || @_basename
75
+ end
76
+
73
77
  def _apps
74
78
  @_apps.empty? ? [self] : @_apps.flatten
75
79
  end
@@ -98,6 +102,7 @@ module Dapp
98
102
  Application.new(self).tap do |app|
99
103
  app.instance_variable_set(:'@_builder', _builder)
100
104
  app.instance_variable_set(:'@_home_path', _home_path)
105
+ app.instance_variable_set(:'@_basename', _basename)
101
106
  app.instance_variable_set(:'@_app_install_dependencies', _app_install_dependencies)
102
107
  app.instance_variable_set(:'@_app_setup_dependencies', _app_setup_dependencies)
103
108
  app.instance_variable_set(:'@_artifact', Marshal.load(Marshal.dump(_artifact)))
@@ -47,15 +47,25 @@ module Dapp
47
47
 
48
48
  # Stage
49
49
  class Stage < Base
50
+ STAGES = [:from, :infra_install, :source_1_archive, :source_1, :app_install, :source_2,
51
+ :infra_setup, :source_3, :chef_cookbooks, :app_setup, :source_4, :source_5].freeze
52
+
50
53
  attr_accessor :_config
51
54
  attr_accessor :_before, :_after
52
55
 
56
+ def initialize(*args)
57
+ super
58
+ raise Error::Config, code: :stage_artifact_not_associated if _before.nil? && _after.nil?
59
+ end
60
+
53
61
  def _before=(stage)
54
62
  @_before = stage.to_sym
63
+ validate_associated_option(option: :before, value: @_before)
55
64
  end
56
65
 
57
66
  def _after=(stage)
58
67
  @_after = stage.to_sym
68
+ validate_associated_option(option: :after, value: @_after)
59
69
  end
60
70
 
61
71
  protected
@@ -63,6 +73,13 @@ module Dapp
63
73
  def code
64
74
  :artifact_unexpected_attribute
65
75
  end
76
+
77
+ private
78
+
79
+ def validate_associated_option(option:, value:)
80
+ return if STAGES.include? value
81
+ raise Error::Config, code: :stage_artifact_incorrect_associated_value, data: { option: option, value: value }
82
+ end
66
83
  end
67
84
  end
68
85
  end
@@ -8,8 +8,8 @@ module Dapp
8
8
  def initialize
9
9
  @_volume = []
10
10
  @_expose = []
11
- @_env = []
12
- @_label = []
11
+ @_env = {}
12
+ @_label = {}
13
13
  @_cmd = []
14
14
  @_onbuild = []
15
15
  end
@@ -28,11 +28,11 @@ module Dapp
28
28
  end
29
29
 
30
30
  def env(**options)
31
- @_env.concat(options_to_args(options))
31
+ @_env.merge!(options)
32
32
  end
33
33
 
34
34
  def label(**options)
35
- @_label.concat(options_to_args(options))
35
+ @_label.merge!(options)
36
36
  end
37
37
 
38
38
  def cmd(*args)
@@ -76,12 +76,6 @@ module Dapp
76
76
  def clone
77
77
  Marshal.load(Marshal.dump(self))
78
78
  end
79
-
80
- private
81
-
82
- def options_to_args(options)
83
- options.map { |key, value| "#{key.upcase}=#{value}" }
84
- end
85
79
  end
86
80
  end
87
81
  end
@@ -4,7 +4,7 @@ module Dapp
4
4
  class Main < Application
5
5
  def initialize(**options)
6
6
  @_home_path = Pathname.new(options[:dappfile_path]).parent.expand_path.to_s
7
- @_name = Pathname.new(@_home_path).basename.to_s
7
+ @_basename = Pathname.new(@_home_path).basename.to_s
8
8
  @_builder = Pathname.new(@_home_path).join('Berksfile').exist? ? :chef : :shell
9
9
 
10
10
  @_docker = Docker.new
@@ -16,7 +16,7 @@ module Dapp
16
16
  end
17
17
 
18
18
  def name(value)
19
- @_name = value
19
+ @_basename = value
20
20
  end
21
21
  end
22
22
  end
@@ -23,7 +23,12 @@ module Dapp
23
23
  end
24
24
 
25
25
  def build
26
- build_configs.each { |config| Application.new(config: config, cli_options: cli_options).build! }
26
+ build_configs.each do |config|
27
+ log_step(config._name)
28
+ with_log_indent do
29
+ Application.new(config: config, cli_options: cli_options).build!
30
+ end
31
+ end
27
32
  end
28
33
 
29
34
  def list
@@ -43,17 +48,12 @@ module Dapp
43
48
  end
44
49
  end
45
50
 
46
- def flush_metadata
47
- build_configs.each do |config|
48
- log(config._name)
49
- app = Application.new(config: config, cli_options: cli_options, ignore_git_fetch: true)
50
- FileUtils.rm_rf app.metadata_path
51
- end
51
+ def stages_flush
52
+ shellout(%{docker rmi $(docker images --format="{{.Repository}}:{{.Tag}}" #{build_configs.first._basename}-dappstage)})
52
53
  end
53
54
 
54
- def self.flush_stages
55
- shellout('docker rmi $(docker images --format="{{.Repository}}:{{.Tag}}" dapp)')
56
- shellout('docker rmi $(docker images -f "dangling=true" -q)')
55
+ def stages_cleanup
56
+ shellout(%{docker rmi $(docker images -f "dangling=true" -f "label=dapp=#{build_configs.first._basename}" -q)})
57
57
  end
58
58
 
59
59
  private
@@ -13,7 +13,7 @@ module Dapp
13
13
  data = desc[:data] || {}
14
14
  ::I18n.t [:common, context, code].join('.'), [:common, code].join('.'), **data, raise: true
15
15
  rescue ::I18n::MissingTranslationData => _e
16
- raise NetStatus::Exception, code: :missing_translation, data: { code: code }
16
+ raise ::NetStatus::Exception, code: :missing_translation, data: { code: code }
17
17
  end
18
18
  end
19
19
  end # Helper
@@ -43,6 +43,7 @@ module Dapp
43
43
  def with_log_indent(with = true)
44
44
  log_indent_next if with
45
45
  yield
46
+ ensure
46
47
  log_indent_prev if with
47
48
  end
48
49
 
@@ -10,12 +10,12 @@ module Dapp
10
10
  add_change_option(:expose, value)
11
11
  end
12
12
 
13
- def add_change_env(value)
14
- add_change_option(:env, value)
13
+ def add_change_env(**options)
14
+ add_change_option(:env, options_to_args(options))
15
15
  end
16
16
 
17
- def add_change_label(value)
18
- add_change_option(:label, value)
17
+ def add_change_label(**options)
18
+ add_change_option(:label, options_to_args(options))
19
19
  end
20
20
 
21
21
  def add_change_cmd(value)
@@ -84,6 +84,10 @@ module Dapp
84
84
  end
85
85
  end
86
86
 
87
+ def options_to_args(options)
88
+ options.map { |key, value| "#{key}=#{value}" }
89
+ end
90
+
87
91
  def prepared_options
88
92
  prepared_options_default(options) { |k, vals| Array(vals).map { |v| "--#{k}=#{v}" }.join(' ') }
89
93
  end
@@ -19,16 +19,10 @@ module Dapp
19
19
  end
20
20
 
21
21
  def build!(**kwargs)
22
- @built_id = if should_be_built?
23
- begin
24
- run!(**kwargs)
25
- commit!
26
- ensure
27
- shellout("docker rm #{container_name}")
28
- end
29
- else
30
- from.built_id
31
- end
22
+ run!(**kwargs)
23
+ @built_id = commit!
24
+ ensure
25
+ shellout("docker rm #{container_name}")
32
26
  end
33
27
 
34
28
  def export!(name, log_verbose: false, log_time: false, force: false)
@@ -65,10 +59,6 @@ module Dapp
65
59
  def commit!
66
60
  shellout!("docker commit #{prepared_change} #{container_name}").stdout.strip
67
61
  end
68
-
69
- def should_be_built?
70
- !(bash_commands.empty? && change_options.empty?)
71
- end
72
62
  end # Stage
73
63
  end # Image
74
64
  end # Dapp
@@ -1,5 +1,5 @@
1
1
  # Version
2
2
  module Dapp
3
- VERSION = '0.3.0'.freeze
3
+ VERSION = '0.3.1'.freeze
4
4
  BUILD_CACHE_VERSION = 1
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dapp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitry Stolyarov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-04 00:00:00.000000000 Z
11
+ date: 2016-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mixlib-shellout
@@ -338,6 +338,8 @@ files:
338
338
  - lib/dapp/build/stage/from.rb
339
339
  - lib/dapp/build/stage/infra_install.rb
340
340
  - lib/dapp/build/stage/infra_setup.rb
341
+ - lib/dapp/build/stage/mod/artifact.rb
342
+ - lib/dapp/build/stage/mod/logging.rb
341
343
  - lib/dapp/build/stage/source_1.rb
342
344
  - lib/dapp/build/stage/source_1_archive.rb
343
345
  - lib/dapp/build/stage/source_2.rb
@@ -353,13 +355,13 @@ files:
353
355
  - lib/dapp/cli.rb
354
356
  - lib/dapp/cli/base.rb
355
357
  - lib/dapp/cli/build.rb
356
- - lib/dapp/cli/flush.rb
357
- - lib/dapp/cli/flush/metadata.rb
358
- - lib/dapp/cli/flush/stages.rb
359
358
  - lib/dapp/cli/list.rb
360
359
  - lib/dapp/cli/push.rb
361
360
  - lib/dapp/cli/run.rb
362
361
  - lib/dapp/cli/smartpush.rb
362
+ - lib/dapp/cli/stages.rb
363
+ - lib/dapp/cli/stages/cleanup.rb
364
+ - lib/dapp/cli/stages/flush.rb
363
365
  - lib/dapp/config/application.rb
364
366
  - lib/dapp/config/artifact.rb
365
367
  - lib/dapp/config/chef.rb