dapp 0.32.10 → 0.33.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/bin/dapp +1 -23
  3. data/config/en/net_status.yml +7 -0
  4. data/lib/dapp.rb +3 -3
  5. data/lib/dapp/dapp.rb +13 -0
  6. data/lib/dapp/dapp/dappfile.rb +2 -2
  7. data/lib/dapp/dapp/deps/base.rb +5 -37
  8. data/lib/dapp/dapp/deps/common.rb +25 -0
  9. data/lib/dapp/dapp/deps/gitartifact.rb +2 -25
  10. data/lib/dapp/dapp/deps/toolchain.rb +1 -23
  11. data/lib/dapp/dapp/logging/base.rb +3 -3
  12. data/lib/dapp/dapp/ruby2go.rb +96 -0
  13. data/lib/dapp/dapp/sentry.rb +0 -1
  14. data/lib/dapp/dapp/shellout/base.rb +4 -2
  15. data/lib/dapp/dimg/build/stage/artifact_base.rb +7 -6
  16. data/lib/dapp/dimg/build/stage/base.rb +37 -7
  17. data/lib/dapp/dimg/build/stage/from.rb +1 -1
  18. data/lib/dapp/dimg/builder/ansible.rb +1 -209
  19. data/lib/dapp/dimg/builder/base.rb +0 -5
  20. data/lib/dapp/dimg/builder/none.rb +1 -34
  21. data/lib/dapp/dimg/builder/ruby2go.rb +51 -0
  22. data/lib/dapp/dimg/builder/shell.rb +1 -25
  23. data/lib/dapp/dimg/cli/command/dimg/bp.rb +10 -15
  24. data/lib/dapp/dimg/cli/command/dimg/build.rb +0 -5
  25. data/lib/dapp/dimg/config/directive/docker/base.rb +1 -1
  26. data/lib/dapp/dimg/dapp/command/build_context/export.rb +1 -1
  27. data/lib/dapp/dimg/dapp/command/build_context/import.rb +1 -1
  28. data/lib/dapp/dimg/dapp/command/cleanup_repo.rb +59 -90
  29. data/lib/dapp/dimg/dapp/command/common.rb +60 -74
  30. data/lib/dapp/dimg/dapp/command/mrproper.rb +2 -17
  31. data/lib/dapp/dimg/dapp/command/stages/cleanup_local.rb +9 -6
  32. data/lib/dapp/dimg/dimg.rb +26 -43
  33. data/lib/dapp/dimg/docker_registry/base/authorization.rb +1 -16
  34. data/lib/dapp/dimg/git_artifact.rb +142 -21
  35. data/lib/dapp/dimg/git_repo/base.rb +11 -0
  36. data/lib/dapp/dimg/git_repo/local.rb +14 -0
  37. data/lib/dapp/dimg/git_repo/remote.rb +25 -34
  38. data/lib/dapp/dimg/image/argument.rb +12 -58
  39. data/lib/dapp/dimg/image/stage.rb +202 -43
  40. data/lib/dapp/kube/kubernetes/client.rb +0 -6
  41. data/lib/dapp/kube/kubernetes/manager/deployment.rb +18 -30
  42. data/lib/dapp/version.rb +1 -1
  43. metadata +8 -8
  44. data/lib/dapp/dimg/builder/ansible/assets.rb +0 -349
  45. data/lib/dapp/dimg/exception/introspect_image.rb +0 -7
  46. data/lib/dapp/dimg/image/docker.rb +0 -144
@@ -58,7 +58,7 @@ module Dapp
58
58
 
59
59
  protected
60
60
 
61
- def _shellout_with_logging!(*args, verbose: false, quiet: true, time: false, **kwargs)
61
+ def _shellout_with_logging!(*args, verbose: false, quiet: true, time: false, raise_on_error: true, **kwargs)
62
62
  stream = Stream.new
63
63
  if verbose && !quiet
64
64
  kwargs[:live_stream] = Proxy::Base.new(stream, STDOUT, with_time: time)
@@ -68,7 +68,9 @@ module Dapp
68
68
  kwargs[:live_stderr] = Proxy::Error.new(stream, with_time: time)
69
69
  end
70
70
 
71
- shellout(*args, **kwargs).tap(&:error!)
71
+ shellout(*args, **kwargs).tap do |res|
72
+ res.error! if raise_on_error
73
+ end
72
74
  rescue ::Mixlib::ShellOut::ShellCommandFailed => e
73
75
  raise Error::Shellout, code: Helper::Trivia.class_to_lowercase(e.class), data: { stream: stream.show }
74
76
  end
@@ -56,12 +56,13 @@ module Dapp
56
56
 
57
57
  def run_artifact_dimg(artifact_dimg, commands)
58
58
  docker_options = ['--rm',
59
- "--volume #{dimg.tmp_path('artifact', artifact_dimg.name )}:#{artifact_dimg.container_tmp_path(artifact_dimg.name)}",
60
- "--volumes-from #{dimg.dapp.toolchain_container}",
61
- "--volumes-from #{dimg.dapp.base_container}",
62
- "--entrypoint #{dimg.dapp.bash_bin}"]
63
- dimg.dapp.log_secondary_process(dimg.dapp.t(code: 'process.artifact_copy', data: { name: artifact_dimg.name }), short: true) do
64
- artifact_dimg.run(docker_options, [%(-ec '#{dimg.dapp.shellout_pack(commands)}')])
59
+ "--volume=#{dimg.tmp_path('artifact', artifact_dimg.name )}:#{artifact_dimg.container_tmp_path(artifact_dimg.name)}",
60
+ "--volumes-from=#{dimg.dapp.toolchain_container}",
61
+ "--volumes-from=#{dimg.dapp.base_container}",
62
+ "--entrypoint=#{dimg.dapp.bash_bin}"]
63
+ dimg.dapp.log_secondary_process(dimg.dapp.t(code: 'process.artifact_copy', data:
64
+ { name: artifact_dimg.name }), short: true) do
65
+ artifact_dimg.run(docker_options, ["-ec", dimg.dapp.shellout_pack(commands)])
65
66
  end
66
67
  rescue Error::Dimg => e
67
68
  raise unless e.net_status[:code] == :dimg_not_run
@@ -17,6 +17,39 @@ module Dapp
17
17
  @next_stage.prev_stage = self
18
18
  end
19
19
 
20
+ def get_ruby2go_state_hash
21
+ {}.tap {|hash|
22
+ # NOTICE: Delete this when stage has been moved to go.
23
+ # NOTICE: This is data for build.StubStage and build.StubImage.
24
+
25
+ hash["Image"] = {
26
+ "Labels" => image.labels
27
+ .map{|k,v| [k.to_s, v.to_s]}
28
+ .to_h,
29
+ "ServiceChangeLabels" => image.send(:service_change_options)
30
+ .fetch(:label, {})
31
+ .map{|k,v| [k.to_s, v.to_s]}
32
+ .to_h,
33
+ }
34
+
35
+ if prev_stage
36
+ hash["PrevStage"] = prev_stage.get_ruby2go_state_hash
37
+ end
38
+ }
39
+ end
40
+
41
+ def set_ruby2go_state_hash(hash)
42
+ if prev_stage
43
+ prev_stage.set_ruby2go_state_hash(hash["PrevStage"])
44
+ end
45
+
46
+ # NOTICE: This is data from build.StubImage.
47
+
48
+ hash["Image"]["ServiceChangeLabels"].each do |k, v|
49
+ image.add_service_change_label(k.to_sym => v)
50
+ end
51
+ end
52
+
20
53
  # rubocop:disable Metrics/PerceivedComplexity
21
54
  def build_lock!
22
55
  return yield if dimg.dapp.dry_run?
@@ -27,14 +60,11 @@ module Dapp
27
60
  no_lock = false
28
61
 
29
62
  dimg.dapp.lock("#{dimg.dapp.name}.image.#{image.name}") do
30
- image.class.reset_image_inspect(image.name)
63
+ image.reset_image_inspect
31
64
 
32
65
  if image_should_be_locked?
33
66
  yield
34
67
  else
35
- stage = self
36
- stage.renew until (stage = stage.next_stage).nil?
37
-
38
68
  no_lock = true
39
69
  end
40
70
  end
@@ -84,7 +114,7 @@ module Dapp
84
114
 
85
115
  if dimg.dapp.ssh_auth_sock
86
116
  image.add_volume "#{dimg.dapp.ssh_auth_sock}:/tmp/dapp-ssh-agent"
87
- image.add_env 'SSH_AUTH_SOCK', '/tmp/dapp-ssh-agent'
117
+ image.add_env SSH_AUTH_SOCK: '/tmp/dapp-ssh-agent'
88
118
  end
89
119
 
90
120
  yield if block_given?
@@ -211,8 +241,8 @@ module Dapp
211
241
 
212
242
  def renew
213
243
  commits_discard
214
- image_reset
215
244
  image_untag! if image_should_be_untagged?
245
+ image_reset
216
246
  end
217
247
 
218
248
  def image_reset
@@ -249,7 +279,7 @@ module Dapp
249
279
 
250
280
  def introspect_image_default(introspected_image)
251
281
  if introspected_image.built?
252
- dimg.introspect_image!(image: introspected_image.built_id, options: image.send(:prepared_options))
282
+ introspected_image.introspect!
253
283
  else
254
284
  dimg.dapp.log_warning(desc: { code: :introspect_image_impossible, data: { name: name } })
255
285
  end
@@ -13,7 +13,7 @@ module Dapp
13
13
  if !from_dimg.nil?
14
14
  process = dimg.dapp.t(code: 'process.layer_building', data: { name: from_dimg.name })
15
15
  dimg.dapp.log_secondary_process(process) { from_dimg.build! }
16
- else
16
+ elsif !from_image.tagged?
17
17
  try_host_docker_login
18
18
  from_image.pull!
19
19
  raise Error::Build, code: :from_image_not_found, data: { name: from_image_name } unless from_image.tagged?
@@ -1,213 +1,5 @@
1
1
  module Dapp
2
2
  module Dimg
3
- class Builder::Ansible < Builder::Base
4
-
5
- ANSIBLE_IMAGE_VERSION = "2.4.4.0-10"
6
-
7
- def ansible_bin
8
- "/.dapp/deps/ansible/#{ANSIBLE_IMAGE_VERSION}/embedded/bin/ansible"
9
- end
10
-
11
- def ansible_playbook_bin
12
- "/.dapp/deps/ansible/#{ANSIBLE_IMAGE_VERSION}/embedded/bin/ansible-playbook"
13
- end
14
-
15
- def python_path
16
- "/.dapp/deps/ansible/#{ANSIBLE_IMAGE_VERSION}/embedded/bin/python"
17
- end
18
-
19
- def ansible_playbook_solo_cmd
20
- "#{ansible_playbook_bin} -c local"
21
- end
22
-
23
- def ansible_image
24
- "dappdeps/ansible:#{ANSIBLE_IMAGE_VERSION}"
25
- end
26
-
27
- def ansible_container_name
28
- "dappdeps_ansible_#{ANSIBLE_IMAGE_VERSION}"
29
- end
30
-
31
- def ansible_container
32
- @ansible_container ||= begin
33
- is_container_exist = proc{dimg.dapp.shellout("#{dimg.dapp.host_docker} inspect #{ansible_container_name}").exitstatus.zero?}
34
- if !is_container_exist.call
35
- dimg.dapp.lock("dappdeps.container.#{ansible_container_name}", default_timeout: 600) do
36
- if !is_container_exist.call
37
- dimg.dapp.log_secondary_process(dimg.dapp.t(code: 'process.ansible_container_creating', data: {name: ansible_container_name}), short: true) do
38
- dimg.dapp.shellout!(
39
- ["#{dimg.dapp.host_docker} create",
40
- "--name #{ansible_container_name}",
41
- "--volume /.dapp/deps/ansible/#{ANSIBLE_IMAGE_VERSION} #{ansible_image}"].join(' ')
42
- )
43
- end
44
- end
45
- end
46
- end
47
- ansible_container_name
48
- end
49
- end
50
-
51
- # query tasks from ansible config
52
- # create dump_config structure
53
- # returns structure:
54
- # { 'tasks' => [array of tasks for stage],
55
- # 'dump_config' => {
56
- # 'dump_config_doc' => 'dump of doc',
57
- # 'dump_config_sections' => {'task_0'=>'dump for task 0', 'task_1'=>'dump for task 1', ... }}
58
- def stage_config(stage)
59
- @stage_configs ||= {}
60
- @stage_configs[stage.to_s] ||= begin
61
- {}.tap do |stage_config|
62
- stage_config['dump_config'] = {
63
- 'dump_config_doc' => dimg.config._ansible['dump_config_doc'],
64
- 'dump_config_sections' => {},
65
- }
66
- stage_config['tasks'] = dimg.config._ansible[stage.to_s].map.with_index do |dapp_task, task_num|
67
- {}.tap do |task|
68
- task.merge!(dapp_task['config'])
69
- task['tags'] = [].tap do |tags|
70
- tags << dapp_task['config']['tags']
71
- dump_tag = "task_#{task_num}"
72
- tags << dump_tag
73
- stage_config['dump_config']['dump_config_sections'][dump_tag] = dapp_task['dump_config_section']
74
- end.flatten.compact
75
- end
76
- end || []
77
- end
78
- end
79
- end
80
-
81
- def stage_playbook(stage)
82
- @stage_playbooks ||= {}
83
- @stage_playbooks[stage.to_s] ||= begin
84
- [{
85
- 'hosts' => 'all',
86
- 'gather_facts' => 'no',
87
- 'tasks' => [],
88
- }].tap do |playbook|
89
- playbook[0]['tasks'].concat(stage_config(stage)['tasks'])
90
- end
91
- end
92
- end
93
-
94
- def create_workdir_structure(stage)
95
- @workdir_structures ||= {}
96
- @workdir_structures[stage.to_s] ||= true.tap do
97
- host_workdir(stage).tap do |workdir|
98
- # playbook with tasks for a stage
99
- workdir.join('playbook.yml').write YAML.dump(stage_playbook(stage))
100
- #puts YAML.dump(stage_playbook(stage))
101
-
102
- # generate inventory with localhost and python in dappdeps-ansible
103
- workdir.join('hosts').write Assets.hosts(python_path)
104
-
105
- # generate ansible config for solo mode
106
- workdir.join('ansible.cfg').write Assets.ansible_cfg(container_workdir.join('hosts'),
107
- container_workdir.join('lib', 'callback'),
108
- dimg.dapp.sudo_bin,
109
- container_tmpdir.join('local'),
110
- container_tmpdir.join('remote'),
111
- )
112
-
113
- # save config dump for pretty errors
114
- workdir.join('dump_config.json').write JSON.generate(stage_config(stage)['dump_config'])
115
-
116
- # python modules
117
- workdir.join('lib').tap do |libdir|
118
- libdir.mkpath
119
- # crypt.py hack
120
- # TODO must be in dappdeps-ansible
121
- libdir.join('crypt.py').write Assets.crypt_py
122
- libdir.join('callback').tap do |callbackdir|
123
- callbackdir.mkpath
124
- callbackdir.join('__init__.py').write '# module callback'
125
- callbackdir.join('live.py').write Assets.live_py
126
- # add dapp specific stdout callback for ansible
127
- callbackdir.join('dapp.py').write Assets.dapp_py
128
- end
129
- end
130
- end
131
- end
132
- end
133
-
134
- %i(before_install install before_setup setup build_artifact).each do |stage|
135
- define_method("#{stage}?") {
136
- !stage_empty?(stage)
137
- }
138
-
139
- define_method("#{stage}_checksum") do
140
- checksum_args = []
141
- (dimg.config._ansible[stage.to_s] || []).each do |task|
142
- checksum_args << JSON.dump(task["config"])
143
- end
144
- checksum_args << public_send("#{stage}_version_checksum")
145
- _checksum checksum_args
146
- end
147
-
148
- define_method("#{stage}_version_checksum") do
149
- _checksum(dimg.config._ansible["#{stage}_version"], dimg.config._ansible['version'])
150
- end
151
-
152
- define_method(stage.to_s) do |image|
153
- unless stage_empty?(stage)
154
- create_workdir_structure(stage)
155
- image.add_env('ANSIBLE_CONFIG', container_workdir.join('ansible.cfg'))
156
- image.add_env('DAPP_DUMP_CONFIG_DOC_PATH', container_workdir.join('dump_config.json'))
157
- image.add_env('PYTHONPATH', container_workdir.join('lib'))
158
- image.add_env('PYTHONIOENCODING', 'utf-8')
159
- image.add_env('ANSIBLE_PREPEND_SYSTEM_PATH', dimg.dapp.dappdeps_base_path)
160
- image.add_volumes_from("#{ansible_container}:rw")
161
- image.add_volume "#{host_workdir(stage)}:#{container_workdir}:ro"
162
- image.add_volume "#{host_tmpdir(stage)}:#{container_tmpdir}:rw"
163
- image.add_command [ansible_playbook_bin,
164
- container_workdir.join('playbook.yml'),
165
- ENV['ANSIBLE_ARGS']
166
- ].compact.join(' ')
167
- end
168
- end
169
- end
170
-
171
- def before_build_check
172
- end
173
-
174
- def before_dimg_should_be_built_check
175
- end
176
-
177
- def stage_empty?(stage)
178
- stage_config(stage)['tasks'].empty? && public_send("#{stage}_version_checksum").nil?
179
- end
180
-
181
- # host directory in tmp_dir with directories structure
182
- def host_workdir(stage)
183
- @host_workdirs ||= {}
184
- @host_workdirs[stage.to_s] ||= begin
185
- dimg.tmp_path(dimg.dapp.consistent_uniq_slugify(dimg.config._name || "nameless"), "ansible-workdir-#{stage}").tap {|p| p.mkpath}
186
- end
187
- end
188
-
189
- # temporary directories for ansible
190
- def host_tmpdir(stage)
191
- @host_tmpdirs ||= {}
192
- @host_tmpdirs[stage.to_s] ||= begin
193
- dimg.tmp_path(dimg.dapp.consistent_uniq_slugify(dimg.config._name || "nameless"), "ansible-tmpdir-#{stage}").tap do |p|
194
- p.mkpath
195
- p.join('local').mkpath
196
- p.join('remote').mkpath
197
- end
198
- end
199
- end
200
-
201
- # directory with playbook in container
202
- def container_workdir
203
- dimg.container_dapp_path("ansible-workdir")
204
- end
205
-
206
- # temporary directory for ansible
207
- def container_tmpdir
208
- dimg.container_dapp_path("ansible-tmpdir")
209
- end
210
-
211
- end # Builder::Ansible
3
+ class Builder::Ansible < Builder::Ruby2Go; end
212
4
  end # Dimg
213
5
  end # Dapp
@@ -72,11 +72,6 @@ module Dapp
72
72
  def build_artifact_checksum
73
73
  raise
74
74
  end
75
-
76
- def _checksum(*args)
77
- return if (format_args = args.flatten.compact.delete_if { |val| val.respond_to?(:empty?) && val.empty? }).empty?
78
- dimg.hashsum format_args
79
- end
80
75
  end # Builder::Base
81
76
  end # Dimg
82
77
  end # Dapp
@@ -1,38 +1,5 @@
1
1
  module Dapp
2
2
  module Dimg
3
- class Builder::None < Builder::Base
4
- def before_dimg_should_be_built_check
5
- end
6
-
7
- def before_install(_image)
8
- end
9
-
10
- def before_install_checksum
11
- end
12
-
13
- def before_setup(_image)
14
- end
15
-
16
- def before_setup_checksum
17
- end
18
-
19
- def install(_image)
20
- end
21
-
22
- def install_checksum
23
- end
24
-
25
- def setup(_image)
26
- end
27
-
28
- def setup_checksum
29
- end
30
-
31
- def build_artifact(_image)
32
- end
33
-
34
- def build_artifact_checksum
35
- end
36
- end # Builder::None
3
+ class Builder::None < Builder::Ruby2Go; end
37
4
  end # Dimg
38
5
  end # Dapp
@@ -0,0 +1,51 @@
1
+ module Dapp
2
+ module Dimg
3
+ class Builder::Ruby2Go < Builder::Base
4
+ [:before_install, :before_setup, :install, :setup, :build_artifact].each do |stage|
5
+ define_method("#{stage}_checksum") do
6
+ command = "#{snake_case_to_camel_case(stage)}Checksum"
7
+ ruby2go_builder_command(command: command)
8
+ end
9
+
10
+ define_method("#{stage}?") do
11
+ command = "Is#{snake_case_to_camel_case(stage)}Empty"
12
+ !ruby2go_builder_command(command: command)
13
+ end
14
+
15
+ define_method(stage.to_s) do |image|
16
+ command = snake_case_to_camel_case(stage)
17
+ ruby2go_builder_command(command: command, image: image.ruby2go_image_option).tap do |data|
18
+ image.set_ruby2go_state_hash(JSON.load(data["image"]))
19
+ end
20
+ end
21
+ end
22
+
23
+ def ruby2go_builder_command(command:, **options)
24
+ builder = self.class.name.split("::").last.downcase
25
+ command_options = {
26
+ builder: builder,
27
+ command: command,
28
+ config: YAML.dump(dimg.config),
29
+ extra: get_ruby2go_state_hash,
30
+ artifact: dimg.artifact?
31
+ }.merge(options)
32
+
33
+ dimg.dapp.ruby2go_builder(command_options).tap do |res|
34
+ raise Error::Build, code: :ruby2go_builder_command_failed_unexpected_error, data: { command: command, message: res["error"] } unless res["error"].nil?
35
+ break res['data']
36
+ end
37
+ end
38
+
39
+ def get_ruby2go_state_hash
40
+ {
41
+ "TmpPath" => dimg.tmp_path.to_s,
42
+ "ContainerDappPath" => dimg.container_dapp_path.to_s,
43
+ }
44
+ end
45
+
46
+ def snake_case_to_camel_case(value)
47
+ value.to_s.split('_').collect(&:capitalize).join
48
+ end
49
+ end # Builder::Shell
50
+ end # Dimg
51
+ end # Dapp