dapp 0.13.3 → 0.13.4

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.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/bin/dapp +0 -13
  3. data/config/en/common.yml +4 -2
  4. data/config/en/net_status.yml +15 -3
  5. data/lib/dapp.rb +11 -6
  6. data/lib/dapp/cli.rb +1 -1
  7. data/lib/dapp/cli/command/base.rb +4 -4
  8. data/lib/dapp/config/directive/base.rb +4 -2
  9. data/lib/dapp/core_ext/hash.rb +14 -0
  10. data/lib/dapp/dapp.rb +32 -6
  11. data/lib/dapp/dapp/dapp_config.rb +85 -0
  12. data/lib/dapp/dapp/dappfile.rb +4 -0
  13. data/lib/dapp/dapp/deps/base.rb +2 -2
  14. data/lib/dapp/dapp/deps/gitartifact.rb +2 -2
  15. data/lib/dapp/dapp/logging/base.rb +5 -5
  16. data/lib/dapp/dapp/logging/process.rb +5 -7
  17. data/lib/dapp/dapp/shellout/base.rb +16 -17
  18. data/lib/dapp/deployment/cli/command/deployment.rb +2 -3
  19. data/lib/dapp/deployment/dapp/command/apply.rb +6 -6
  20. data/lib/dapp/deployment/dapp/dapp.rb +0 -1
  21. data/lib/dapp/deployment/kube_app.rb +1 -1
  22. data/lib/dapp/deployment/kube_base.rb +1 -1
  23. data/lib/dapp/dimg/build/stage/artifact_base.rb +3 -8
  24. data/lib/dapp/dimg/build/stage/base.rb +57 -38
  25. data/lib/dapp/dimg/build/stage/docker_instructions.rb +1 -1
  26. data/lib/dapp/dimg/build/stage/from.rb +6 -2
  27. data/lib/dapp/dimg/build/stage/ga_archive_dependencies.rb +2 -2
  28. data/lib/dapp/dimg/build/stage/ga_artifact_patch.rb +1 -5
  29. data/lib/dapp/dimg/build/stage/ga_base.rb +1 -14
  30. data/lib/dapp/dimg/build/stage/ga_latest_patch.rb +7 -31
  31. data/lib/dapp/dimg/build/stage/ga_related_dependencies_base.rb +21 -0
  32. data/lib/dapp/dimg/build/stage/import_artifact.rb +10 -3
  33. data/lib/dapp/dimg/build/stage/install/ga_post_install_patch_dependencies.rb +3 -3
  34. data/lib/dapp/dimg/build/stage/install/ga_pre_install_patch_dependencies.rb +3 -3
  35. data/lib/dapp/dimg/build/stage/mod/group.rb +19 -7
  36. data/lib/dapp/dimg/build/stage/mod/logging.rb +7 -20
  37. data/lib/dapp/dimg/build/stage/setup/ga_post_setup_patch_dependencies.rb +1 -1
  38. data/lib/dapp/dimg/build/stage/setup/ga_pre_setup_patch_dependencies.rb +3 -3
  39. data/lib/dapp/dimg/builder/chef.rb +2 -2
  40. data/lib/dapp/dimg/builder/chef/cookbook.rb +2 -2
  41. data/lib/dapp/dimg/cli/command/dimg.rb +1 -1
  42. data/lib/dapp/dimg/cli/command/dimg/build.rb +15 -8
  43. data/lib/dapp/dimg/config/directive/artifact_base.rb +13 -4
  44. data/lib/dapp/dimg/config/directive/dimg/instance_methods.rb +1 -1
  45. data/lib/dapp/dimg/config/directive/dimg/validation.rb +6 -1
  46. data/lib/dapp/dimg/config/directive/docker/base.rb +1 -2
  47. data/lib/dapp/dimg/config/directive/git_artifact_local.rb +3 -0
  48. data/lib/dapp/dimg/config/directive/git_artifact_remote.rb +1 -1
  49. data/lib/dapp/dimg/config/directive/mount.rb +9 -1
  50. data/lib/dapp/dimg/dapp/command/build_context/export.rb +13 -15
  51. data/lib/dapp/dimg/dapp/command/build_context/import.rb +3 -3
  52. data/lib/dapp/dimg/dapp/command/cleanup.rb +1 -1
  53. data/lib/dapp/dimg/dapp/command/common.rb +17 -6
  54. data/lib/dapp/dimg/dapp/command/mrproper.rb +9 -4
  55. data/lib/dapp/dimg/dapp/command/stages/cleanup_local.rb +19 -17
  56. data/lib/dapp/dimg/dapp/command/stages/cleanup_repo.rb +1 -1
  57. data/lib/dapp/dimg/dimg.rb +5 -5
  58. data/lib/dapp/dimg/dimg/git_artifact.rb +11 -6
  59. data/lib/dapp/dimg/dimg/path.rb +2 -6
  60. data/lib/dapp/dimg/git_artifact.rb +118 -66
  61. data/lib/dapp/dimg/git_repo/base.rb +1 -1
  62. data/lib/dapp/dimg/git_repo/own.rb +1 -1
  63. data/lib/dapp/dimg/git_repo/remote.rb +23 -14
  64. data/lib/dapp/dimg/image/docker.rb +11 -11
  65. data/lib/dapp/dimg/image/scratch.rb +33 -9
  66. data/lib/dapp/dimg/image/stage.rb +3 -3
  67. data/lib/dapp/helper/cli.rb +8 -0
  68. data/lib/dapp/helper/tar.rb +31 -0
  69. data/lib/dapp/kube/cli/command/kube.rb +5 -4
  70. data/lib/dapp/kube/cli/command/kube/deploy.rb +5 -0
  71. data/lib/dapp/kube/cli/command/kube/minikube_setup.rb +13 -0
  72. data/lib/dapp/kube/cli/command/kube/{secret_file_encrypt.rb → secret_extract.rb} +3 -3
  73. data/lib/dapp/kube/cli/command/kube/secret_generate.rb +11 -1
  74. data/lib/dapp/kube/client.rb +1 -1
  75. data/lib/dapp/kube/client/error.rb +1 -1
  76. data/lib/dapp/kube/dapp/command/common.rb +29 -4
  77. data/lib/dapp/kube/dapp/command/deploy.rb +43 -21
  78. data/lib/dapp/kube/dapp/command/dismiss.rb +1 -1
  79. data/lib/dapp/{deployment → kube}/dapp/command/minikube_setup.rb +12 -12
  80. data/lib/dapp/kube/dapp/command/secret_extract.rb +46 -0
  81. data/lib/dapp/kube/dapp/command/secret_generate.rb +33 -4
  82. data/lib/dapp/kube/dapp/dapp.rb +3 -2
  83. data/lib/dapp/kube/error/kubernetes.rb +7 -0
  84. data/lib/dapp/kube/secret.rb +1 -1
  85. data/lib/dapp/version.rb +2 -2
  86. metadata +11 -7
  87. data/lib/dapp/deployment/cli/command/deployment/minikube_setup.rb +0 -13
  88. data/lib/dapp/kube/dapp/command/secret_file_encrypt.rb +0 -22
@@ -63,7 +63,7 @@ module Dapp
63
63
  @_git_artifact ||= GitArtifact.new(dapp: dapp)
64
64
  end
65
65
 
66
- [:build_dir, :tmp_dir].each do |mount_type|
66
+ [:build_dir, :tmp_dir, :custom_dir].each do |mount_type|
67
67
  define_method "_#{mount_type}_mount" do
68
68
  _mount.select { |m| m._type == mount_type }
69
69
  end
@@ -29,11 +29,16 @@ module Dapp
29
29
  elm.validate! if elm.respond_to?(:validate!)
30
30
  end
31
31
  end
32
+ _mount.map(&:_to).tap do |mounts_points|
33
+ mounts_points.each do |path|
34
+ raise Error::Config, code: :mount_duplicate_to, data: { path: path } if mounts_points.count(path) > 1
35
+ end
36
+ end
32
37
  end
33
38
 
34
39
  def validate_scratch_directives!
35
40
  directives = [[:_shell, :shell], [:_chef, :chef], [:_git_artifact, :git],
36
- [:_tmp_dir_mount, :mount], [:_build_dir_mount, :mount]]
41
+ [:_tmp_dir_mount, :mount], [:_build_dir_mount, :mount], [:_custom_dir_mount, :mount]]
37
42
  directives.each do |name, user_name|
38
43
  raise Error::Config,
39
44
  code: :scratch_unsupported_directive,
@@ -10,8 +10,7 @@ module Dapp
10
10
  sub_directive_eval do
11
11
  image = image.to_s
12
12
  raise(Error::Config, code: :docker_from_incorrect, data: { name: image }) unless ::Dapp::Dimg::Image::Docker.image_name?(image)
13
- raise(Error::Config, code: :docker_from_without_tag, data: { name: image }) unless image.include?(':')
14
- @_from = image
13
+ @_from = image.include?(':') ? image : [image, 'latest'].join(':')
15
14
  @_from_cache_version = cache_version
16
15
  end
17
16
  end
@@ -3,6 +3,9 @@ module Dapp
3
3
  module Config
4
4
  module Directive
5
5
  class GitArtifactLocal < ArtifactBase
6
+ def export(absolute_dir_path = '/', &blk)
7
+ super
8
+ end
6
9
  alias add export
7
10
  undef_method :export
8
11
 
@@ -13,7 +13,7 @@ module Dapp
13
13
  end
14
14
 
15
15
  def branch(value)
16
- sub_directive_eval { @_branch = value }
16
+ sub_directive_eval { @_branch = value.to_s }
17
17
  end
18
18
 
19
19
  def commit(value)
@@ -4,6 +4,7 @@ module Dapp
4
4
  module Directive
5
5
  class Mount < Base
6
6
  attr_reader :_to
7
+ attr_reader :_from
7
8
  attr_reader :_type
8
9
 
9
10
  def initialize(to, **kwargs, &blk)
@@ -21,8 +22,15 @@ module Dapp
21
22
  end
22
23
  end
23
24
 
25
+ def from_path(path)
26
+ sub_directive_eval do
27
+ @_from = path_format(path)
28
+ @_type = :custom_dir
29
+ end
30
+ end
31
+
24
32
  def validate!
25
- raise Error::Config, code: :mount_from_required if _type.nil?
33
+ raise Error::Config, code: :mount_from_or_from_path_required if _type.nil?
26
34
  end
27
35
  end
28
36
  end
@@ -20,27 +20,25 @@ module Dapp
20
20
  end.flatten
21
21
 
22
22
  log_secondary_process(:images, short: true) do
23
- Image::Docker.save!(context_images_names, build_context_images_tar)
23
+ Image::Docker.save!(context_images_names, build_context_images_tar, verbose: true, quiet: log_quiet?)
24
24
  end unless context_images_names.empty?
25
25
  end
26
26
  end
27
27
 
28
28
  def export_build_context_build_tar
29
29
  log_secondary_process(:build_dir, short: true) do
30
- File.open(build_context_build_tar, File::RDWR | File::CREAT) do |f|
31
- Gem::Package::TarWriter.new(f) do |tar|
32
- Dir.glob(File.join(build_path, '**/*'), File::FNM_DOTMATCH).each do |path|
33
- archive_file_path = path
34
- .reverse
35
- .chomp(build_path.to_s.reverse)
36
- .chomp('/')
37
- .reverse
38
- if File.directory?(path)
39
- tar.mkdir archive_file_path, File.stat(path).mode
40
- else
41
- tar.add_file archive_file_path, File.stat(path).mode do |tf|
42
- tf.write File.read(path)
43
- end
30
+ tar_write(build_context_build_tar) do |tar|
31
+ Dir.glob(File.join(build_path, '**/*'), File::FNM_DOTMATCH).each do |path|
32
+ archive_file_path = path
33
+ .reverse
34
+ .chomp(build_path.to_s.reverse)
35
+ .chomp('/')
36
+ .reverse
37
+ if File.directory?(path)
38
+ tar.mkdir archive_file_path, File.stat(path).mode
39
+ else
40
+ tar.add_file archive_file_path, File.stat(path).mode do |tf|
41
+ tf.write File.read(path)
44
42
  end
45
43
  end
46
44
  end
@@ -20,7 +20,7 @@ module Dapp
20
20
  if build_context_images_tar.exist?
21
21
  log_secondary_process(:images, short: true) do
22
22
  lock("#{name}.images") do
23
- Image::Docker.load!(build_context_images_tar)
23
+ Image::Docker.load!(build_context_images_tar, verbose: true, quiet: log_quiet?)
24
24
  end
25
25
  end
26
26
  else
@@ -33,8 +33,8 @@ module Dapp
33
33
  log_secondary_process(:build_dir, short: true) do
34
34
  store_current_build_dir
35
35
 
36
- File.open(build_context_build_tar, File::RDONLY) do |f|
37
- Gem::Package::TarReader.new(f).each_entry do |entry|
36
+ tar_read(build_context_build_tar) do |tar|
37
+ tar.each_entry do |entry|
38
38
  header = entry.header
39
39
  path = File.join(build_path, entry.full_name)
40
40
 
@@ -9,7 +9,7 @@ module Dapp
9
9
  dapp_containers_flush
10
10
  dapp_dangling_images_flush
11
11
  remove_images_by_query([
12
- 'docker images',
12
+ "#{host_docker_bin} images",
13
13
  %(--format '{{if ne "#{stage_cache}" .Repository }}{{.Repository}}:{{.Tag}}{{ end }}'),
14
14
  %(-f "label=dapp=#{stage_dapp_label}")
15
15
  ].join(' ')) # FIXME: negative filter is not currently supported by the Docker CLI
@@ -6,19 +6,19 @@ module Dapp
6
6
  protected
7
7
 
8
8
  def dapp_images_names
9
- shellout!(%(docker images --format="{{.Repository}}:{{.Tag}}" #{stage_cache})).stdout.lines.map(&:strip)
9
+ shellout!(%(#{host_docker_bin} images --format="{{.Repository}}:{{.Tag}}" #{stage_cache})).stdout.lines.map(&:strip)
10
10
  end
11
11
 
12
12
  def dapp_images_ids
13
- shellout!(%(docker images #{stage_cache} -q --no-trunc)).stdout.lines.map(&:strip)
13
+ shellout!(%(#{host_docker_bin} images #{stage_cache} -q --no-trunc)).stdout.lines.map(&:strip)
14
14
  end
15
15
 
16
16
  def dapp_containers_flush
17
- remove_containers_by_query(%(docker ps -a -f "label=dapp" -f "name=#{container_name_prefix}" -q), force: true)
17
+ remove_containers_by_query(%(#{host_docker_bin} ps -a -f "label=dapp" -f "name=#{container_name_prefix}" -q), force: true)
18
18
  end
19
19
 
20
20
  def dapp_dangling_images_flush
21
- remove_images_by_query(%(docker images -f "dangling=true" -f "label=dapp=#{stage_dapp_label}" -q), force: true)
21
+ remove_images_by_query(%(#{host_docker_bin} images -f "dangling=true" -f "label=dapp=#{stage_dapp_label}" -q), force: true)
22
22
  end
23
23
 
24
24
  def remove_images_by_query(images_query, force: false)
@@ -26,7 +26,18 @@ module Dapp
26
26
  end
27
27
 
28
28
  def remove_images(ids, force: false)
29
- remove_base('docker rmi%{force_option} %{ids}', ids.uniq, force: force)
29
+ ids.uniq!
30
+ check_user_containers!(ids) unless force
31
+ remove_base("#{host_docker_bin} rmi%{force_option} %{ids}", ids, force: force)
32
+ end
33
+
34
+ def check_user_containers!(images_ids)
35
+ return if images_ids.empty?
36
+ log_step_with_indent(:'check user containers') do
37
+ run_command(%(#{host_docker_bin} ps -a -q #{images_ids.uniq.map { |image_id| "--filter=ancestor=#{image_id}" }.join(' ')})).tap do |res|
38
+ raise Error::Command, code: :user_containers_detected, data: { ids: res.stdout.strip } if !res.stdout.strip.empty? && !dry_run?
39
+ end
40
+ end
30
41
  end
31
42
 
32
43
  def remove_containers_by_query(containers_query, force: false)
@@ -34,7 +45,7 @@ module Dapp
34
45
  end
35
46
 
36
47
  def remove_containers(ids, force: false)
37
- remove_base('docker rm%{force_option} %{ids}', ids.uniq, force: force)
48
+ remove_base("#{host_docker_bin} rm%{force_option} %{ids}", ids.uniq, force: force)
38
49
  end
39
50
 
40
51
  def remove_base(query_format, ids, force: false)
@@ -12,6 +12,7 @@ module Dapp
12
12
 
13
13
  if proper_all?
14
14
  flush_by_label('dapp')
15
+ remove_build_dir
15
16
  elsif proper_dev_mode_cache?
16
17
  flush_by_label('dapp-dev-mode')
17
18
  elsif proper_cache_version?
@@ -31,6 +32,10 @@ module Dapp
31
32
  log_step_with_indent(:images) { dapp_images_flush_by_label(label) }
32
33
  end
33
34
 
35
+ def remove_build_dir
36
+ log_step_with_indent(:build_dir) { FileUtils.rm_rf(build_path) }
37
+ end
38
+
34
39
  def proper_all?
35
40
  !!options[:proper_all]
36
41
  end
@@ -40,11 +45,11 @@ module Dapp
40
45
  end
41
46
 
42
47
  def dapp_containers_flush_by_label(label)
43
- remove_containers_by_query(%(docker ps -a -f "label=#{label}" -q), force: true)
48
+ remove_containers_by_query(%(#{host_docker_bin} ps -a -f "label=#{label}" -q), force: true)
44
49
  end
45
50
 
46
51
  def dapp_dangling_images_flush_by_label(label)
47
- remove_images_by_query(%(docker images -f "dangling=true" -f "label=#{label}" -q), force: true)
52
+ remove_images_by_query(%(#{host_docker_bin} images -f "dangling=true" -f "label=#{label}" -q), force: true)
48
53
  end
49
54
 
50
55
  def dapp_images_flush_by_label(label)
@@ -54,7 +59,7 @@ module Dapp
54
59
 
55
60
  def dapp_images_by_label(label)
56
61
  @dapp_images ||= begin
57
- shellout!(%(docker images -f "dangling=false" --format="{{.Repository}}:{{.Tag}}" -f "label=#{label}"))
62
+ shellout!(%(#{host_docker_bin} images -f "dangling=false" --format="{{.Repository}}:{{.Tag}}" -f "label=#{label}"))
58
63
  .stdout
59
64
  .lines
60
65
  .map(&:strip)
@@ -63,7 +68,7 @@ module Dapp
63
68
 
64
69
  def proper_cache_all_images
65
70
  shellout!([
66
- 'docker images',
71
+ "#{host_docker_bin} images",
67
72
  '--format="{{.Repository}}:{{.Tag}}"',
68
73
  %(-f "label=dapp-cache-version=#{::Dapp::BUILD_CACHE_VERSION}" -f "dangling=false")
69
74
  ].join(' ')).stdout.lines.map(&:strip)
@@ -4,15 +4,15 @@ module Dapp
4
4
  module Command
5
5
  module Stages
6
6
  module CleanupLocal
7
- def stages_cleanup_local(repo)
8
- lock_repo(repo, readonly: true) do
7
+ def stages_cleanup_local
8
+ lock_repo(option_repo, readonly: true) do
9
9
  raise Error::Command, code: :stages_cleanup_required_option unless stages_cleanup_option?
10
10
 
11
11
  dapp_containers_flush
12
12
 
13
- proper_cache if proper_cache_version?
14
- stages_cleanup_by_repo(repo) if proper_repo_cache?
15
- proper_git_commit if proper_git_commit?
13
+ proper_cache if proper_cache_version?
14
+ stages_cleanup_by_repo if proper_repo_cache?
15
+ proper_git_commit if proper_git_commit?
16
16
  end
17
17
  end
18
18
 
@@ -28,8 +28,8 @@ module Dapp
28
28
  end
29
29
  end
30
30
 
31
- def stages_cleanup_by_repo(repo)
32
- registry = registry(repo)
31
+ def stages_cleanup_by_repo
32
+ registry = registry(option_repo)
33
33
  repo_dimgs = repo_dimgs_images(registry)
34
34
 
35
35
  lock("#{name}.images") do
@@ -49,16 +49,18 @@ module Dapp
49
49
  end
50
50
 
51
51
  def actual_cache_images
52
- shellout!([
53
- 'docker images',
54
- '--format="{{.Repository}}:{{.Tag}}"',
55
- %(-f "label=dapp-cache-version=#{::Dapp::BUILD_CACHE_VERSION}"),
56
- stage_cache
57
- ].join(' ')).stdout.lines.map(&:strip)
52
+ @actual_cache_images ||= begin
53
+ shellout!([
54
+ "#{host_docker_bin} images",
55
+ '--format="{{.Repository}}:{{.Tag}}"',
56
+ %(-f "label=dapp-cache-version=#{::Dapp::BUILD_CACHE_VERSION}"),
57
+ stage_cache
58
+ ].join(' ')).stdout.lines.map(&:strip)
59
+ end
58
60
  end
59
61
 
60
62
  def dapp_images_hash
61
- shellout!(%(docker images --format "{{.Repository}}:{{.Tag}};{{.ID}}" --no-trunc #{stage_cache})).stdout.lines.map do |line|
63
+ shellout!(%(#{host_docker_bin} images --format "{{.Repository}}:{{.Tag}};{{.ID}}" --no-trunc #{stage_cache})).stdout.lines.map do |line|
62
64
  line.strip.split(';')
63
65
  end.to_h
64
66
  end
@@ -77,7 +79,7 @@ module Dapp
77
79
  end
78
80
 
79
81
  def image_exist?(image_id)
80
- shellout!(%(docker inspect #{image_id}))
82
+ shellout!(%(#{host_docker_bin} inspect #{image_id}))
81
83
  true
82
84
  rescue ::Dapp::Error::Shellout
83
85
  false
@@ -88,7 +90,7 @@ module Dapp
88
90
  end
89
91
 
90
92
  def image_parent(image_id)
91
- shellout!(%(docker inspect -f {{.Parent}} #{image_id})).stdout.strip
93
+ shellout!(%(#{host_docker_bin} inspect -f {{.Parent}} #{image_id})).stdout.strip
92
94
  end
93
95
 
94
96
  def proper_git_commit
@@ -107,7 +109,7 @@ module Dapp
107
109
  def dapp_images_detailed
108
110
  @dapp_images_detailed ||= {}.tap do |images|
109
111
  dapp_images_names.each do |image_name|
110
- shellout!(%(docker inspect --format='{{json .}}' #{image_name})).stdout.strip.tap do |output|
112
+ shellout!(%(#{host_docker_bin} inspect --format='{{json .}}' #{image_name})).stdout.strip.tap do |output|
111
113
  images[image_name] = output == 'null' ? {} : JSON.parse(output)
112
114
  end
113
115
  end
@@ -112,7 +112,7 @@ module Dapp
112
112
 
113
113
  def remove_repo_images(registry, tags)
114
114
  tags.each do |tag|
115
- log(tag) if dry_run? || log_verbose?
115
+ log(tag) if log_verbose? || dry_run?
116
116
  registry.image_delete(tag) unless dry_run?
117
117
  end
118
118
  end
@@ -122,7 +122,7 @@ module Dapp
122
122
  end
123
123
 
124
124
  def run(docker_options, command)
125
- cmd = "docker run #{[docker_options, last_stage.image.built_id, command].flatten.compact.join(' ')}"
125
+ cmd = "#{dapp.host_docker_bin} run #{[docker_options, last_stage.image.built_id, command].flatten.compact.join(' ')}"
126
126
  if dapp.dry_run?
127
127
  dapp.log(cmd)
128
128
  else
@@ -159,7 +159,7 @@ module Dapp
159
159
  end
160
160
 
161
161
  def introspect_image!(image:, options:)
162
- cmd = "docker run -ti --rm --entrypoint #{dapp.bash_bin} #{options} #{image}"
162
+ cmd = "#{dapp.host_docker_bin} run -ti --rm --entrypoint #{dapp.bash_bin} #{options} #{image}"
163
163
  system(cmd)
164
164
  end
165
165
 
@@ -169,9 +169,9 @@ module Dapp
169
169
  # Чтобы от них избавиться — запускаем docker-контейнер под root-пользователем
170
170
  # и удаляем примонтированную tmp-директорию.
171
171
  cmd = "".tap do |cmd|
172
- cmd << "docker run --rm"
173
- cmd << " --volume #{tmp_base_dir}:#{tmp_base_dir}"
174
- cmd << " ubuntu:16.04"
172
+ cmd << "#{dapp.host_docker_bin} run --rm"
173
+ cmd << " --volume #{dapp.tmp_base_dir}:#{dapp.tmp_base_dir}"
174
+ cmd << " alpine:3.6"
175
175
  cmd << " rm -rf #{tmp_path}"
176
176
  end
177
177
  dapp.shellout! cmd
@@ -7,17 +7,22 @@ module Dapp
7
7
  end
8
8
 
9
9
  def local_git_artifacts
10
- @local_git_artifact_list ||= Array(config._git_artifact._local).map do |ga_config|
10
+ @local_git_artifact_list ||= begin
11
11
  repo = GitRepo::Own.new(self)
12
- ::Dapp::Dimg::GitArtifact.new(repo, **ga_config._artifact_options)
12
+ Array(config._git_artifact._local).map do |ga_config|
13
+ ::Dapp::Dimg::GitArtifact.new(repo, **ga_config._artifact_options)
14
+ end
13
15
  end
14
16
  end
15
17
 
16
18
  def remote_git_artifacts
17
- @remote_git_artifact_list ||= Array(config._git_artifact._remote).map do |ga_config|
18
- repo = GitRepo::Remote.new(self, ga_config._name, url: ga_config._url)
19
- repo.fetch!(ga_config._branch)
20
- ::Dapp::Dimg::GitArtifact.new(repo, **ga_config._artifact_options)
19
+ @remote_git_artifact_list ||= begin
20
+ repos = {}
21
+ Array(config._git_artifact._remote).map do |ga_config|
22
+ repo_key = [ga_config._url, ga_config._branch]
23
+ repos[repo_key] ||= GitRepo::Remote.new(self, ga_config._name, url: ga_config._url).tap { |repo| repo.fetch!(ga_config._branch) }
24
+ ::Dapp::Dimg::GitArtifact.new(repos[repo_key], **ga_config._artifact_options)
25
+ end
21
26
  end
22
27
  end
23
28
  end # GitArtifact
@@ -6,17 +6,13 @@ module Dapp
6
6
  dapp.path(*path).expand_path
7
7
  end
8
8
 
9
- def tmp_base_dir
10
- File.expand_path(dapp.options[:tmp_dir_prefix] || '/tmp')
11
- end
12
-
13
9
  def tmp_path(*path)
14
- @tmp_path ||= Dir.mktmpdir('dapp-', tmp_base_dir)
10
+ @tmp_path ||= Dir.mktmpdir('dapp-', dapp.tmp_base_dir)
15
11
  make_path(@tmp_path, *path).expand_path.tap { |p| p.parent.mkpath }
16
12
  end
17
13
 
18
14
  def build_path(*path)
19
- make_path(dapp.build_path, *path).expand_path.tap { |p| p.parent.mkpath }
15
+ dapp.build_path(*path).expand_path.tap { |p| p.parent.mkpath }
20
16
  end
21
17
 
22
18
  def container_dapp_path(*path)
@@ -2,6 +2,8 @@ module Dapp
2
2
  module Dimg
3
3
  # Git repo artifact
4
4
  class GitArtifact
5
+ include Helper::Tar
6
+
5
7
  attr_reader :repo
6
8
  attr_reader :name
7
9
 
@@ -31,45 +33,61 @@ module Dapp
31
33
 
32
34
  [].tap do |commands|
33
35
  commands << "#{repo.dimg.dapp.install_bin} #{credentials.join(' ')} -d #{to}"
34
- if any_changes?(nil, stage.layer_commit(self))
35
- commands << "#{sudo}#{repo.dimg.dapp.tar_bin} -xf #{archive_file(stage.layer_commit(self))} -C #{to}"
36
+ if archive_any_changes?(stage)
37
+ commands << "#{sudo}#{repo.dimg.dapp.tar_bin} -xf #{archive_file(*archive_stage_commits(stage))} -C #{to}"
36
38
  end
37
39
  end
38
40
  end
39
41
 
40
42
  def apply_patch_command(stage)
41
- patch_command(stage.prev_g_a_stage.layer_commit(self), stage.layer_commit(self))
42
- end
43
-
44
- def apply_dev_patch_command(stage)
45
- patch_command(stage.prev_g_a_stage.layer_commit(self), nil)
43
+ [].tap do |commands|
44
+ if dev_mode?
45
+ if any_changes?(*dev_patch_stage_commits(stage))
46
+ changed_files = diff_patches(*dev_patch_stage_commits(stage)).map {|p| File.join(to, cwd, p.delta.new_file[:path])}
47
+ commands << "#{sudo}#{repo.dimg.dapp.rm_bin} -rf #{changed_files.join(' ')}"
48
+ commands << "#{sudo}#{repo.dimg.dapp.tar_bin} -xf #{archive_file(*dev_patch_stage_commits(stage))} -C #{to}"
49
+ end
50
+ else
51
+ if patch_any_changes?(stage)
52
+ commands << "#{sudo}#{repo.dimg.dapp.git_bin} apply --whitespace=nowarn --directory=#{to} --unsafe-paths #{patch_file(*patch_stage_commits(stage))}"
53
+ end
54
+ end
55
+ end
46
56
  end
47
57
 
48
58
  def stage_dependencies_checksum(stage)
49
59
  return [] if (stage_dependencies = stages_dependencies[stage.name]).empty?
50
60
 
51
61
  paths = (include_paths(true) + base_paths(stage_dependencies, true)).uniq
62
+ to_commit = dev_mode? ? nil : latest_commit
52
63
 
53
- to_commit = if repo.is_a? GitRepo::Own and repo.dimg.dev_mode?
54
- nil
55
- else
56
- latest_commit
57
- end
64
+ stage_dependencies_key = [stage.name, to_commit]
65
+ @stage_dependencies_checksums ||= {}
66
+ @stage_dependencies_checksums[stage_dependencies_key] = begin
67
+ if @stage_dependencies_checksums.key?(stage_dependencies_key)
68
+ @stage_dependencies_checksums[stage_dependencies_key]
69
+ else
70
+ if (patches = diff_patches(nil, to_commit, paths: paths)).empty?
71
+ repo.dimg.dapp.log_warning(desc: { code: :stage_dependencies_not_found,
72
+ data: { repo: repo.respond_to?(:url) ? repo.url : 'local',
73
+ dependencies: stage_dependencies.join(', ') } })
74
+ end
58
75
 
59
- diff_patches(nil, to_commit, paths: paths)
60
- .sort_by {|patch| patch.delta.new_file[:path]}
61
- .reduce(nil) {|prev_hash, patch|
62
- Digest::SHA256.hexdigest [
63
- prev_hash,
64
- patch.delta.new_file[:path],
65
- patch.delta.new_file[:mode].to_s,
66
- patch.to_s
67
- ].compact.join(':::')
68
- }
76
+ patches.sort_by {|patch| patch.delta.new_file[:path]}
77
+ .reduce(nil) {|prev_hash, patch|
78
+ Digest::SHA256.hexdigest [
79
+ prev_hash,
80
+ patch.delta.new_file[:path],
81
+ patch.delta.new_file[:mode].to_s,
82
+ patch.to_s
83
+ ].compact.join(':::')
84
+ }
85
+ end
86
+ end
69
87
  end
70
88
 
71
- def patch_size(from, to)
72
- diff_patches(from, to).reduce(0) do |bytes, patch|
89
+ def patch_size(from_commit, to_commit)
90
+ diff_patches(from_commit, to_commit).reduce(0) do |bytes, patch|
73
91
  patch.hunks.each do |hunk|
74
92
  hunk.lines.each do |l|
75
93
  bytes +=
@@ -85,8 +103,13 @@ module Dapp
85
103
  end
86
104
  end
87
105
 
88
- def dev_patch_hash(stage)
89
- Digest::SHA256.hexdigest diff_patches(stage.prev_g_a_stage.layer_commit(self), nil).map(&:to_s).join(':::')
106
+ def dev_patch_hash
107
+ return unless dev_mode?
108
+
109
+ Digest::SHA256.hexdigest(diff_patches(latest_commit, nil).map do |patch|
110
+ next unless (path = repo.path.dirname.join(patch.delta.new_file[:path])).file?
111
+ File.read(path)
112
+ end.join(':::'))
90
113
  end
91
114
 
92
115
  def latest_commit
@@ -101,8 +124,12 @@ module Dapp
101
124
  "#{repo.name}#{name ? "_#{name}" : nil}"
102
125
  end
103
126
 
104
- def any_changes?(from, to = latest_commit)
105
- diff_patches(from, to).any?
127
+ def archive_any_changes?(stage)
128
+ any_changes?(*archive_stage_commits(stage))
129
+ end
130
+
131
+ def patch_any_changes?(stage)
132
+ any_changes?(*patch_stage_commits(stage))
106
133
  end
107
134
 
108
135
  protected
@@ -115,35 +142,34 @@ module Dapp
115
142
  attr_reader :group
116
143
  attr_reader :stages_dependencies
117
144
 
118
- def patch_command(prev_commit, current_commit)
119
- [].tap do |commands|
120
- if any_changes?(prev_commit, current_commit)
121
- commands << "#{sudo}#{repo.dimg.dapp.git_bin} apply --whitespace=nowarn --directory=#{to} --unsafe-paths " \
122
- "#{patch_file(prev_commit, current_commit)}"
123
- end
124
- end
125
- end
126
-
127
145
  def sudo
128
146
  repo.dimg.dapp.sudo_command(owner: owner, group: group)
129
147
  end
130
148
 
131
- def archive_file(to_commit)
132
- create_file(repo.dimg.tmp_path('archives', archive_file_name(to_commit))) do |f|
133
- Gem::Package::TarWriter.new(f) do |tar|
134
- diff_patches(nil, to_commit).each do |patch|
135
- entry = patch.delta.new_file
136
- if entry[:mode] == 40960 # symlink
137
- tar.add_symlink slice_cwd(entry[:path]), repo.lookup_object(entry[:oid]).content, entry[:mode]
149
+ def archive_file(from_commit, to_commit)
150
+ tar_write(repo.dimg.tmp_path('archives', archive_file_name(from_commit, to_commit))) do |tar|
151
+ diff_patches(from_commit, to_commit).each do |patch|
152
+ entry = patch.delta.new_file
153
+
154
+ content = begin
155
+ if to_commit == nil
156
+ next unless (path = repo.path.dirname.join(entry[:path])).file?
157
+ File.read(path)
138
158
  else
139
- tar.add_file slice_cwd(entry[:path]), entry[:mode] do |tf|
140
- tf.write repo.lookup_object(entry[:oid]).content
141
- end
159
+ repo.lookup_object(entry[:oid]).content
160
+ end
161
+ end
162
+
163
+ if entry[:mode] == 40960 # symlink
164
+ tar.add_symlink slice_cwd(entry[:path]), content, entry[:mode]
165
+ else
166
+ tar.add_file slice_cwd(entry[:path]), entry[:mode] do |tf|
167
+ tf.write content
142
168
  end
143
169
  end
144
170
  end
145
171
  end
146
- repo.dimg.container_tmp_path('archives', archive_file_name(to_commit))
172
+ repo.dimg.container_tmp_path('archives', archive_file_name(from_commit, to_commit))
147
173
  rescue Gem::Package::TooLongFileName => e
148
174
  raise Error::TarWriter, message: e.message
149
175
  end
@@ -156,15 +182,15 @@ module Dapp
156
182
  .reverse
157
183
  end
158
184
 
159
- def archive_file_name(commit)
160
- file_name(commit, 'tar')
185
+ def archive_file_name(from_commit, to_commit)
186
+ file_name(from_commit, to_commit, 'tar')
161
187
  end
162
188
 
163
- def patch_file(from, to)
164
- create_file(repo.dimg.tmp_path('patches', patch_file_name(from, to))) do |f|
165
- diff_patches(from, to).each { |patch| f.write change_patch_new_file_path(patch) }
189
+ def patch_file(from_commit, to_commit)
190
+ File.open(repo.dimg.tmp_path('patches', patch_file_name(from_commit, to_commit)), File::RDWR | File::CREAT) do |f|
191
+ diff_patches(from_commit, to_commit).each { |patch| f.write change_patch_new_file_path(patch) }
166
192
  end
167
- repo.dimg.container_tmp_path('patches', patch_file_name(from, to))
193
+ repo.dimg.container_tmp_path('patches', patch_file_name(from_commit, to_commit))
168
194
  end
169
195
 
170
196
  # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
@@ -209,23 +235,25 @@ module Dapp
209
235
  patch.delta.old_file[:mode] != patch.delta.new_file[:mode]
210
236
  end
211
237
 
212
- def patch_file_name(from, to)
213
- file_name(from, to, 'patch')
238
+ def patch_file_name(from_commit, to_commit)
239
+ file_name(from_commit, to_commit, 'patch')
214
240
  end
215
241
 
216
242
  def file_name(*args, ext)
217
- "#{[full_name, args].flatten.join('_')}.#{ext}"
243
+ "#{[paramshash, args].flatten.compact.join('_')}.#{ext}"
218
244
  end
219
245
 
220
- def create_file(file_path, &blk)
221
- File.open(file_path, File::RDWR | File::CREAT, &blk)
222
- end
223
-
224
- def diff_patches(from, to, paths: include_paths_or_cwd)
225
- (@diff_patches ||= {})[[from, to, paths]] ||= repo.patches(from, to,
226
- paths: paths,
227
- exclude_paths: exclude_paths(true),
228
- force_text: true)
246
+ def diff_patches(from_commit, to_commit, paths: include_paths_or_cwd)
247
+ (@diff_patches ||= {})[[from_commit, to_commit, paths]] ||= begin
248
+ options = {}.tap do |opts|
249
+ opts[:force_text] = true
250
+ if dev_mode?
251
+ opts[:include_untracked] = true
252
+ opts[:recurse_untracked_dirs] = true
253
+ end
254
+ end
255
+ repo.patches(from_commit, to_commit, paths: paths, exclude_paths: exclude_paths(true), **options)
256
+ end
229
257
  end
230
258
 
231
259
  def include_paths_or_cwd
@@ -257,6 +285,30 @@ module Dapp
257
285
  .reverse
258
286
  end
259
287
  end
288
+
289
+ def archive_stage_commits(stage)
290
+ [nil, stage.layer_commit(self)]
291
+ end
292
+
293
+ def patch_stage_commits(stage)
294
+ [stage.prev_g_a_stage.layer_commit(self), stage.layer_commit(self)]
295
+ end
296
+
297
+ def dev_patch_stage_commits(stage)
298
+ [stage.prev_g_a_stage.layer_commit(self), nil]
299
+ end
300
+
301
+ def any_changes?(from_commit, to_commit)
302
+ diff_patches(from_commit, to_commit).any?
303
+ end
304
+
305
+ def dev_mode?
306
+ local? && repo.dimg.dev_mode?
307
+ end
308
+
309
+ def local?
310
+ repo.is_a? GitRepo::Own
311
+ end
260
312
  end
261
313
  end
262
314
  end