dapp 0.24.3 → 0.24.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 882b3acc8506bb005b8bf2a68aa9d1ac3e0cb432
4
- data.tar.gz: b40f3e4feda32bc080ed2ba8e6e5316a5dff9d6f
3
+ metadata.gz: c9a285aead0a2e57006e54a0839ab32cf4170529
4
+ data.tar.gz: cd58972b2de67689e2173bffe9524a0623e79bc1
5
5
  SHA512:
6
- metadata.gz: de722da958bc9b7610cd54f87d2c0b6362ed0828f7a086b9bb707f0f7d83b373e39eaa995dd6a603232c1c2aaf086f25b81cc881f18d8e6412a26a5334e8bf37
7
- data.tar.gz: 4ddc1ed3725f9c7434c3bd1fd6fd85a665dec825001188a2f8314919fa8a386af6934241de2d82abac07e9cb2ab7192ec052565b3dc9f6fab0aceccb4eecd08e
6
+ metadata.gz: 9dbb053e622ce8ac204b9529dbf2c1ca266b22a4f46fec3736963861b5e74148ff19f423e297c1a3a9d0fd44afeeb787c3a448978ab2d0219273a23448eca36f
7
+ data.tar.gz: f15547e0e17c93ba3e39ec915a1413b6445392212c9779333aa9d6742888b86d1291ee6d4be3f830dc79a21fe7af88001b32a428fbf64111da2d58eba3842772
@@ -44,6 +44,7 @@ en:
44
44
  expected_only_one_tag: 'Expected only one tag (`%{tags}`)!'
45
45
  kube_deploy_timeout: "Deploy timeout!"
46
46
  kube_connect_timeout: "Connect timeout when connecting to kube API."
47
+ kube_helm_failed: "Helm failed: %{output}"
47
48
  dapp:
48
49
  no_such_dimg: "No such dimg: `%{dimgs_patterns}`!"
49
50
  no_such_app: "No such app: `%{apps_patterns}`!"
@@ -80,7 +81,7 @@ en:
80
81
  stage_artifact_double_associate: "Can't use `%{stage}` stage for artifact; already used in `%{conflict_stage}` stage!"
81
82
  stage_artifact_not_supported_associated_stage: "Bad artifact stage `%{stage}`!"
82
83
  git_artifact_remote_branch_with_commit: "Remote git repo: use `commit` or `branch` directive!"
83
- artifact_conflict: "Conflict between artifacts paths!"
84
+ artifact_conflict: "Conflict between artifacts!\n\n%{dappfile_context}"
84
85
  scratch_unsupported_directive: "Scratch dimg has unsupported directive `%{directive}`!"
85
86
  scratch_artifact_required: "Scratch dimg without artifacts!"
86
87
  scratch_artifact_associated: "Scratch artifact can't be associated: not expected `before`/`after` attribute!"
@@ -115,7 +116,7 @@ en:
115
116
  rugged:
116
117
  git_repository_reference_error: "Git repo `%{name}`: %{message}!"
117
118
  rugged_remote_error: "Remote git repo `%{url}`: `%{message}`!"
118
- local_git_repository_does_not_exist: "Local git repo: doesn't exist!"
119
+ local_git_repository_does_not_exist: "Local git repo (`%{path}`): doesn't exist!"
119
120
  commit_not_found_in_local_git_repository: "Local git repo: commit `%{commit}` not found!\nIf commit has been rebased: run command `dapp dimg stages cleanup local --improper-git-commit`!"
120
121
  commit_not_found_in_remote_git_repository: "Remote git repo `%{url}`: commit `%{commit}` not found!\nIf commit has been rebased: run command `dapp dimg stages cleanup local --improper-git-commit`!"
121
122
  branch_not_exist_in_remote_git_repository: "Remote git repo `%{url}`: branch `%{branch}` not exist!"
@@ -136,6 +137,8 @@ en:
136
137
  server_connection_refused: "Kube server `%{url}` connection refused: %{error}"
137
138
  server_error: "Kube respond with server error code %{response_http_status}, request parameters: `%{request_parameters}`, response: `%{response_raw_body}`"
138
139
  container_stuck: "Pod's `%{pod_name}` container `%{container_name}` stuck in %{state} state: %{state_reason}: %{state_message}"
140
+ bad_image: "Pod `%{pod_name}` bad image: %{reason}: %{message}"
141
+ container_crash: "Pod's `%{pod_name}` container crashed: %{reason}: %{message}"
139
142
  secret:
140
143
  bad_data: "Data `%{data}` can't be decrypted: check encryption key and data!"
141
144
  key_length_too_short: "Encryption key isn't valid (required size %{required_size} bytes)!"
@@ -232,6 +232,7 @@ require 'dapp/dimg/dapp/command/build_context/export'
232
232
  require 'dapp/dimg/dapp/command/build_context/import'
233
233
  require 'dapp/dimg/dapp/command/build_context/common'
234
234
  require 'dapp/dimg/dapp/dappfile'
235
+ require 'dapp/dimg/dapp/dimg'
235
236
  require 'dapp/dimg/dapp/dapp'
236
237
  require 'dapp/dimg/docker_registry'
237
238
  require 'dapp/dimg/docker_registry/base/request'
@@ -254,6 +255,7 @@ require 'dapp/dimg/lock/base'
254
255
  require 'dapp/dimg/lock/file'
255
256
  require 'dapp/dimg/filelock'
256
257
  require 'dapp/dimg/git_repo/base'
258
+ require 'dapp/dimg/git_repo/local'
257
259
  require 'dapp/dimg/git_repo/own'
258
260
  require 'dapp/dimg/git_repo/remote'
259
261
  require 'dapp/dimg/git_artifact'
@@ -71,11 +71,14 @@ module Dapp
71
71
  end
72
72
 
73
73
  def git_own_repo_exist?
74
- git_own_repo.exist?
74
+ !git_own_repo.nil?
75
75
  end
76
76
 
77
77
  def git_own_repo
78
78
  @git_own_repo ||= Dimg::GitRepo::Own.new(self)
79
+ rescue Dimg::Error::Rugged => e
80
+ raise unless e.net_status[:code] == :local_git_repository_does_not_exist
81
+ nil
79
82
  end
80
83
 
81
84
  def path(*path)
@@ -22,9 +22,8 @@ module Dapp
22
22
  def artifacts
23
23
  @artifacts ||= begin
24
24
  dimg.config.public_send("_#{name}").map do |artifact|
25
- artifact_dimg = ::Dapp::Dimg::Artifact.new(config: artifact._config,
26
- dapp: dimg.dapp,
27
- ignore_git_fetch: dimg.ignore_git_fetch)
25
+ artifact_dimg = dimg.dapp.artifact_dimg(config: artifact._config,
26
+ ignore_git_fetch: dimg.ignore_git_fetch)
28
27
  { name: artifact._config._name, options: artifact._artifact_options, dimg: artifact_dimg }
29
28
  end
30
29
  end
@@ -5,13 +5,6 @@ module Dapp
5
5
  class ArtifactDimg < Dimg
6
6
  def validate_scratch!
7
7
  end
8
-
9
- def validate_artifacts_artifacts!
10
- end
11
-
12
- def validated_artifacts
13
- _git_artifact._local + _git_artifact._remote
14
- end
15
8
  end
16
9
  end
17
10
  end
@@ -136,6 +136,7 @@ module Dapp
136
136
 
137
137
  def artifacts_after_parsing!
138
138
  _artifacts_auto_excluding!
139
+ _artifact.map(&:_config).each(&:artifacts_after_parsing!)
139
140
  end
140
141
 
141
142
  protected
@@ -71,12 +71,39 @@ module Dapp
71
71
  verifiable_artifact = artifacts.shift
72
72
  artifacts.select { |a| a[:to] == verifiable_artifact[:to] }.each do |artifact|
73
73
  next if verifiable_artifact[:index] == artifact[:index]
74
- validate_artifact!(verifiable_artifact, artifact)
75
- validate_artifact!(artifact, verifiable_artifact)
74
+ begin
75
+ validate_artifact!(verifiable_artifact, artifact)
76
+ validate_artifact!(artifact, verifiable_artifact)
77
+ rescue ::Dapp::Error::Config => e
78
+ conflict_between_artifacts!(artifact, verifiable_artifact) if e.net_status[:code] == :artifact_conflict
79
+ raise
80
+ end
76
81
  end
77
82
  end
78
83
  end
79
84
 
85
+ def conflict_between_artifacts!(*formatted_artifacts)
86
+ artifacts = formatted_artifacts.flatten.map { |formatted_artifact| formatted_artifact[:related_artifact] }
87
+ dappfile_context = artifacts.map do |artifact|
88
+ artifact_directive = []
89
+ artifact_directive << begin
90
+ if artifact.is_a? Artifact::Export
91
+ "artifact.export('#{artifact._cwd}') do"
92
+ else
93
+ "git#{"('#{artifact._url}')" if artifact.respond_to?(:_url)}.add('#{artifact._cwd}') do"
94
+ end
95
+ end
96
+ [:include_paths, :exclude_paths].each do |directive|
97
+ next if (paths = artifact.send("_#{directive}")).empty?
98
+ artifact_directive << " #{directive} '#{paths.join("', '")}'"
99
+ end
100
+ artifact_directive << " to '#{artifact._to}'"
101
+ artifact_directive << 'end'
102
+ artifact_directive.join("\n")
103
+ end.join("\n\n")
104
+ raise ::Dapp::Error::Config, code: :artifact_conflict, data: { dappfile_context: dappfile_context }
105
+ end
106
+
80
107
  def validate_artifact_format(artifacts)
81
108
  artifacts.map do |a|
82
109
  path_format = proc { |path| File.expand_path(File.join('/', path, '/'))[1..-1] }
@@ -104,7 +131,8 @@ module Dapp
104
131
  index: artifacts.index(a),
105
132
  to: to,
106
133
  include_paths: include_paths,
107
- exclude_paths: exclude_paths
134
+ exclude_paths: exclude_paths,
135
+ related_artifact: a
108
136
  }
109
137
  end
110
138
  end
@@ -113,17 +141,26 @@ module Dapp
113
141
  verifiable_artifact[:include_paths].each do |verifiable_path|
114
142
  potential_conflicts = artifact[:include_paths].select { |path| path.start_with?(verifiable_path) }
115
143
  validate_artifact_path!(verifiable_artifact, potential_conflicts)
116
- end.empty? && verifiable_artifact[:exclude_paths].empty? && raise(::Dapp::Error::Config, code: :artifact_conflict)
117
- validate_artifact_path!(verifiable_artifact, artifact[:include_paths]) if verifiable_artifact[:include_paths].empty?
144
+ end
145
+
146
+ if verifiable_artifact[:include_paths].empty?
147
+ if artifact[:include_paths].empty? || verifiable_artifact[:exclude_paths].empty?
148
+ raise ::Dapp::Error::Config, code: :artifact_conflict
149
+ else
150
+ validate_artifact_path!(verifiable_artifact, artifact[:include_paths])
151
+ end
152
+ end
118
153
  end
119
154
 
120
155
  def validate_artifact_path!(verifiable_artifact, potential_conflicts)
121
- potential_conflicts.all? do |path|
122
- loop do
123
- break if verifiable_artifact[:exclude_paths].include?(path) || ((path = File.dirname(path)) == '.')
156
+ raise ::Dapp::Error::Config, code: :artifact_conflict unless begin
157
+ potential_conflicts.all? do |path|
158
+ loop do
159
+ break if verifiable_artifact[:exclude_paths].include?(path) || ((path = File.dirname(path)) == '.')
160
+ end
161
+ verifiable_artifact[:exclude_paths].include?(path)
124
162
  end
125
- verifiable_artifact[:exclude_paths].include?(path)
126
- end.tap { |res| res || raise(::Dapp::Error::Config, code: :artifact_conflict) }
163
+ end
127
164
  end
128
165
 
129
166
  def _associated_artifacts
@@ -8,7 +8,7 @@ module Dapp
8
8
 
9
9
  build_configs.each do |config|
10
10
  log_dimg_name_with_indent(config) do
11
- Dimg.new(config: config, dapp: self).build!
11
+ dimg(config: config).build!
12
12
  end
13
13
  end
14
14
  rescue ::Dapp::Error::Shellout, Error::Default
@@ -14,7 +14,7 @@ module Dapp
14
14
  def export_build_context_image_tar
15
15
  lock("#{name}.images", readonly: true) do
16
16
  context_images_names = build_configs.map do |config|
17
- Dimg.new(config: config, dapp: self, ignore_git_fetch: true).tagged_images.map(&:name)
17
+ dimg(config: config, ignore_git_fetch: true).tagged_images.map(&:name)
18
18
  end.flatten
19
19
 
20
20
  log_secondary_process(:images, short: true) do
@@ -123,9 +123,7 @@ module Dapp
123
123
  validate_repo_name!(repo)
124
124
  build_configs.each do |config|
125
125
  log_dimg_name_with_indent(config) do
126
- Dimg.new(config: config, dapp: self, ignore_git_fetch: true, should_be_built: should_be_built).tap do |dimg|
127
- yield dimg
128
- end
126
+ yield dimg(config: config, ignore_git_fetch: true, should_be_built: should_be_built)
129
127
  end
130
128
  end
131
129
  end
@@ -6,7 +6,7 @@ module Dapp
6
6
  def run(docker_options, command)
7
7
  one_dimg!
8
8
  setup_ssh_agent
9
- Dimg.new(config: build_configs.first, dapp: self, ignore_git_fetch: true, should_be_built: true).run(docker_options, command)
9
+ dimg(config: build_configs.first, ignore_git_fetch: true, should_be_built: true).run(docker_options, command)
10
10
  end
11
11
  end
12
12
  end
@@ -5,7 +5,7 @@ module Dapp
5
5
  module StageImage
6
6
  def stage_image
7
7
  one_dimg!
8
- puts Dimg.new(config: build_configs.first, dapp: self, ignore_git_fetch: true).stage_image_name(options[:stage])
8
+ puts dimg(config: build_configs.first, ignore_git_fetch: true).stage_image_name(options[:stage])
9
9
  end
10
10
  end
11
11
  end
@@ -56,7 +56,7 @@ module Dapp
56
56
  def dapp_git_repositories
57
57
  @dapp_git_repositories ||= begin
58
58
  {}.tap do |repositories|
59
- dimgs = build_configs.map { |config| Dimg.new(config: config, dapp: self, ignore_git_fetch: true) }
59
+ dimgs = build_configs.map { |config| dimg(config: config, ignore_git_fetch: true) }
60
60
  dimgs.each do |dimg|
61
61
  [dimg, dimg.artifacts]
62
62
  .flatten
@@ -3,6 +3,7 @@ module Dapp
3
3
  module Dapp
4
4
  module Dapp
5
5
  include Dappfile
6
+ include Dimg
6
7
 
7
8
  include Command::Common
8
9
  include Command::Run
@@ -0,0 +1,15 @@
1
+ module Dapp
2
+ module Dimg
3
+ module Dapp
4
+ module Dimg
5
+ def dimg(config:, **kwargs)
6
+ (@dimgs ||= {})[config._name] ||= ::Dapp::Dimg::Dimg.new(config: config, dapp: self, **kwargs)
7
+ end
8
+
9
+ def artifact_dimg(config:, **kwargs)
10
+ (@artifacts_dimgs ||= {})[config._name] ||= ::Dapp::Dimg::Artifact.new(config: config, dapp: self, **kwargs)
11
+ end
12
+ end # Dimg
13
+ end # Dapp
14
+ end # Dimg
15
+ end # Dapp
@@ -8,8 +8,9 @@ module Dapp
8
8
 
9
9
  def local_git_artifacts
10
10
  @local_git_artifact_list ||= [].tap do |artifacts|
11
+ break artifacts if (local_git_artifacts = Array(config._git_artifact._local)).empty?
11
12
  repo = GitRepo::Own.new(self)
12
- Array(config._git_artifact._local).map do |ga_config|
13
+ local_git_artifacts.map do |ga_config|
13
14
  artifacts.concat(generate_git_artifacts(repo, **ga_config._artifact_options))
14
15
  end
15
16
  end
@@ -27,14 +28,14 @@ module Dapp
27
28
  def generate_git_artifacts(repo, **git_artifact_options)
28
29
  [].tap do |artifacts|
29
30
  artifacts << (artifact = ::Dapp::Dimg::GitArtifact.new(repo, **git_artifact_options))
30
- artifacts.concat(generate_git_submodules_artifacts(artifact))
31
+ artifacts.concat(generate_git_embedded_artifacts(artifact))
31
32
  end
32
33
  end
33
34
 
34
- def generate_git_submodules_artifacts(artifact)
35
+ def generate_git_embedded_artifacts(artifact)
35
36
  [].tap do |artifacts|
36
- artifacts.concat(submodules_artifacts = artifact.submodules_artifacts)
37
- artifacts.concat(submodules_artifacts.map(&method(:generate_git_submodules_artifacts)).flatten)
37
+ artifacts.concat(submodules_artifacts = artifact.embedded_artifacts)
38
+ artifacts.concat(submodules_artifacts.map(&method(:generate_git_embedded_artifacts)).flatten)
38
39
  end
39
40
  end
40
41
  end # GitArtifact
@@ -33,6 +33,10 @@ module Dapp
33
33
  end
34
34
  # rubocop:enable Metrics/ParameterLists
35
35
 
36
+ def embedded_artifacts
37
+ [submodules_artifacts, nested_git_directory_artifacts].flatten
38
+ end
39
+
36
40
  def submodules_artifacts
37
41
  commit = dev_mode? ? nil : latest_commit
38
42
  repo.submodules_params(commit,
@@ -41,65 +45,72 @@ module Dapp
41
45
  end
42
46
 
43
47
  def submodule_artifact(submodule_params)
44
- submodule_rel_path = submodule_params[:path]
45
- submodule_repo = begin
46
- GitRepo::Remote.new(repo.dimg, submodule_rel_path,
47
- url: submodule_url(submodule_params[:url])).tap { |r| r.fetch!(submodule_params[:branch]) }
48
- rescue Rugged::InvalidError => e
49
- raise Error::Rugged, code: :incorrect_gitmodules_file, data: { error: e.message }
50
- end
48
+ embedded_artifact(submodule_params)
49
+ rescue Rugged::InvalidError => e
50
+ raise Error::Rugged, code: :incorrect_gitmodules_file, data: { error: e.message }
51
+ end
51
52
 
52
- self.class.new(submodule_repo, submodule_artifact_options(submodule_params))
53
+ def nested_git_directory_artifacts
54
+ return [] unless dev_mode?
55
+ repo
56
+ .nested_git_directories_patches(paths: include_paths_or_cwd, exclude_paths: exclude_paths(true), **diff_patches_options)
57
+ .map(&method(:nested_git_directory_artifact))
53
58
  end
54
59
 
55
- def submodule_url(url)
56
- if url.start_with?('../')
57
- case repo.remote_origin_url_protocol
58
- when :http, :https, :git
59
- uri = URI.parse(repo.remote_origin_url)
60
- uri.path = File.expand_path(File.join(uri.path, url))
61
- uri.to_s
62
- when :ssh
63
- host_with_user, group_and_project = repo.remote_origin_url.split(':', 2)
64
- group_and_project = File.expand_path(File.join('/', group_and_project, url))[1..-1]
65
- [host_with_user, group_and_project].join(':')
60
+ def nested_git_directory_artifact(patch)
61
+ params = {}.tap do |p|
62
+ p[:path] = patch.delta.new_file[:path]
63
+ p[:type] = :local
64
+ end
65
+ embedded_artifact(params)
66
+ end
67
+
68
+ def embedded_artifact(embedded_params)
69
+ embedded_rel_path = embedded_params[:path]
70
+ embedded_repo = begin
71
+ if embedded_params[:type] == :remote
72
+ GitRepo::Remote.new(repo.dimg, embedded_rel_path,
73
+ url: embedded_params[:url]).tap { |r| r.fetch!(embedded_params[:branch]) }
74
+ elsif embedded_params[:type] == :local
75
+ embedded_path = File.join(repo.workdir_path, embedded_params[:path])
76
+ GitRepo::Local.new(repo.dimg, embedded_rel_path, embedded_path)
66
77
  else
67
78
  raise
68
79
  end
69
- else
70
- url
71
80
  end
81
+
82
+ self.class.new(embedded_repo, embedded_artifact_options(embedded_params))
72
83
  end
73
84
 
74
- def submodule_artifact_options(submodule_params)
75
- submodule_rel_path = submodule_params[:path]
85
+ def embedded_artifact_options(embedded_params)
86
+ embedded_rel_path = embedded_params[:path]
76
87
 
77
88
  {}.tap do |options|
78
- options[:name] = repo.dapp.consistent_uniq_slugify("submodule-#{submodule_rel_path}")
79
- options[:cwd] = submodule_inherit_path(cwd, submodule_rel_path).last
80
- options[:to] = File.join(to, submodule_rel_path)
81
- options[:include_paths] = submodule_inherit_paths(include_paths, submodule_rel_path)
82
- options[:exclude_paths] = submodule_inherit_paths(exclude_paths, submodule_rel_path)
89
+ options[:name] = repo.dapp.consistent_uniq_slugify("embedded-#{embedded_rel_path}")
90
+ options[:cwd] = embedded_inherit_path(cwd, embedded_rel_path).last
91
+ options[:to] = File.join(to, embedded_rel_path)
92
+ options[:include_paths] = embedded_inherit_paths(include_paths, embedded_rel_path)
93
+ options[:exclude_paths] = embedded_inherit_paths(exclude_paths, embedded_rel_path)
83
94
  options[:stages_dependencies] = begin
84
95
  stages_dependencies
85
- .map { |stage, paths| [stage, submodule_inherit_paths(paths, submodule_rel_path)] }
96
+ .map { |stage, paths| [stage, embedded_inherit_paths(paths, embedded_rel_path)] }
86
97
  .to_h
87
98
  end
88
- options[:branch] = submodule_params[:branch]
99
+ options[:branch] = embedded_params[:branch]
89
100
  options[:owner] = owner
90
101
  options[:group] = group
91
102
  end
92
103
  end
93
104
 
94
- def submodule_inherit_paths(paths, submodule_rel_path)
105
+ def embedded_inherit_paths(paths, embedded_rel_path)
95
106
  paths
96
- .select { |path| check_path?(submodule_rel_path, path) || check_subpath?(submodule_rel_path, path) }
97
- .map { |path| submodule_inherit_path(path, submodule_rel_path) }
107
+ .select { |path| check_path?(embedded_rel_path, path) || check_subpath?(embedded_rel_path, path) }
108
+ .map { |path| embedded_inherit_path(path, embedded_rel_path) }
98
109
  .flatten
99
110
  .compact
100
111
  end
101
112
 
102
- def submodule_inherit_path(path, submodule_rel_path)
113
+ def embedded_inherit_path(path, embedded_rel_path)
103
114
  path_parts = path.split('/')
104
115
  test_path = nil
105
116
  inherited_paths = []
@@ -107,7 +118,7 @@ module Dapp
107
118
  last_part_path = path_parts.shift
108
119
  test_path = [test_path, last_part_path].compact.join('/')
109
120
 
110
- non_match = !File.fnmatch(test_path, submodule_rel_path, File::FNM_PATHNAME)
121
+ non_match = !File.fnmatch(test_path, embedded_rel_path, File::FNM_PATHNAME)
111
122
  part_for_all = (last_part_path == '**')
112
123
 
113
124
  if non_match || part_for_all
@@ -462,16 +473,23 @@ module Dapp
462
473
 
463
474
  def diff_patches(from_commit, to_commit, paths: include_paths_or_cwd)
464
475
  (@diff_patches ||= {})[[from_commit, to_commit, paths]] ||= begin
465
- options = {}.tap do |opts|
466
- opts[:force_text] = true
467
- if dev_mode?
468
- opts[:include_untracked] = true
469
- opts[:recurse_untracked_dirs] = true
476
+ repo
477
+ .patches(from_commit, to_commit, paths: paths, exclude_paths: exclude_paths(true), **diff_patches_options)
478
+ .select do |patch|
479
+ file_mode = patch.delta.new_file[:mode]
480
+ !(submodule_mode?(file_mode) || # FIXME: https://github.com/libgit2/rugged/issues/727
481
+ nested_git_directory_mode?(file_mode))
470
482
  end
483
+ end
484
+ end
485
+
486
+ def diff_patches_options
487
+ {}.tap do |opts|
488
+ opts[:force_text] = true
489
+ if dev_mode?
490
+ opts[:include_untracked] = true
491
+ opts[:recurse_untracked_dirs] = true
471
492
  end
472
- repo
473
- .patches(from_commit, to_commit, paths: paths, exclude_paths: exclude_paths(true), **options)
474
- .select { |patch| !submodule_mode?(patch.delta.new_file[:mode]) } # FIXME: https://github.com/libgit2/rugged/issues/727
475
493
  end
476
494
  end
477
495
 
@@ -479,6 +497,10 @@ module Dapp
479
497
  mode == 0o160000
480
498
  end
481
499
 
500
+ def nested_git_directory_mode?(mode)
501
+ mode == 0o040000
502
+ end
503
+
482
504
  def include_paths_or_cwd
483
505
  case
484
506
  when !include_paths(true).empty? then include_paths(true)
@@ -530,7 +552,7 @@ module Dapp
530
552
  end
531
553
 
532
554
  def local?
533
- repo.is_a? GitRepo::Own
555
+ repo.is_a? GitRepo::Local
534
556
  end
535
557
  end
536
558
  end
@@ -63,6 +63,10 @@ module Dapp
63
63
  url_protocol(remote_origin_url)
64
64
  end
65
65
 
66
+ def nested_git_directories_patches(*_args)
67
+ raise
68
+ end
69
+
66
70
  def submodules_params(commit, paths: [], exclude_paths: [])
67
71
  raise "Workdir not supported for #{self.class}" if commit.nil?
68
72
 
@@ -82,10 +86,31 @@ module Dapp
82
86
  .map do |_, params|
83
87
  params = params.symbolize_keys
84
88
  params[:branch] = params[:branch].to_s if params.key?(:branch)
89
+ params[:url] = submodule_url(params[:url])
90
+ params[:type] = url_protocol(params[:url]) == :noname ? :local : :remote
85
91
  params
86
92
  end
87
93
  end
88
94
 
95
+ def submodule_url(gitsubmodule_url)
96
+ if gitsubmodule_url.start_with?('../')
97
+ case remote_origin_url_protocol
98
+ when :http, :https, :git
99
+ uri = URI.parse(remote_origin_url)
100
+ uri.path = File.expand_path(File.join(uri.path, gitsubmodule_url))
101
+ uri.to_s
102
+ when :ssh
103
+ host_with_user, group_and_project = remote_origin_url.split(':', 2)
104
+ group_and_project = File.expand_path(File.join('/', group_and_project, gitsubmodule_url))[1..-1]
105
+ [host_with_user, group_and_project].join(':')
106
+ else
107
+ raise
108
+ end
109
+ else
110
+ gitsubmodule_url
111
+ end
112
+ end
113
+
89
114
  # FIXME: Убрать логику исключения путей exclude_paths из данного класса,
90
115
  # FIXME: т.к. большинство методов не поддерживают инвариант
91
116
  # FIXME "всегда выдавать данные с исключенными путями".
@@ -98,16 +123,14 @@ module Dapp
98
123
 
99
124
  def patches(from, to, paths: [], exclude_paths: [], **kwargs)
100
125
  diff(from, to, **kwargs).patches.select do |patch|
101
- delta_new_file = patch.delta.new_file
102
- args = [delta_new_file[:path], paths: paths, exclude_paths: exclude_paths]
103
- if delta_new_file[:mode] == 0o040000 # nested git repository in dev mode
104
- !ignore_directory?(*args)
105
- else
106
- !ignore_path?(*args)
107
- end
126
+ ignore_patch?(patch, paths: paths, exclude_paths: exclude_paths)
108
127
  end
109
128
  end
110
129
 
130
+ def ignore_patch?(patch, paths: [], exclude_paths: [])
131
+ !ignore_path?(patch.delta.new_file[:path], paths: paths, exclude_paths: exclude_paths)
132
+ end
133
+
111
134
  def entries(commit, paths: [], exclude_paths: [])
112
135
  [].tap do |entries|
113
136
  lookup_commit(commit).tree.walk(:preorder) do |root, entry|
@@ -183,13 +206,6 @@ module Dapp
183
206
  git.lookup(commit)
184
207
  end
185
208
 
186
- def exist?
187
- git
188
- true
189
- rescue Rugged::OSError
190
- false
191
- end
192
-
193
209
  protected
194
210
 
195
211
  attr_reader :manager
@@ -0,0 +1,95 @@
1
+ module Dapp
2
+ module Dimg
3
+ module GitRepo
4
+ class Local < Base
5
+ attr_reader :path
6
+
7
+ def initialize(manager, name, path)
8
+ super(manager, name)
9
+ self.path = path
10
+ end
11
+
12
+ def path=(path)
13
+ @path ||= Pathname(Rugged::Repository.new(path).path)
14
+ rescue Rugged::RepositoryError, Rugged::OSError => _e
15
+ raise Error::Rugged, code: :local_git_repository_does_not_exist, data: { path: path }
16
+ end
17
+
18
+ def workdir_path
19
+ Pathname(git.workdir)
20
+ end
21
+
22
+ def nested_git_directories_patches(paths: [], exclude_paths: [], **kwargs)
23
+ patches(nil, nil, paths: paths, exclude_paths: exclude_paths, **kwargs).select do |patch|
24
+ delta_new_file = patch.delta.new_file
25
+ nested_git_repository_mode?(delta_new_file[:mode])
26
+ end
27
+ end
28
+
29
+ # NOTICE: Параметры {from: nil, to: nil} можно указать только для Own repo.
30
+ # NOTICE: Для Remote repo такой вызов не имеет смысла и это ошибка пользователя класса Remote.
31
+
32
+ def submodules_params(commit, paths: [], exclude_paths: [])
33
+ return super unless commit.nil?
34
+ return [] unless File.file?((gitmodules_file_path = File.join(workdir_path, '.gitmodules')))
35
+
36
+ submodules_params_base(File.read(gitmodules_file_path),
37
+ paths: paths,
38
+ exclude_paths: exclude_paths).each do |submodule_params|
39
+ submodule_path = File.join(workdir_path, submodule_params[:path])
40
+ if git_repo_exist?(submodule_path)
41
+ dapp.log_info("Using local submodule `#{submodule_path}`!")
42
+ submodule_params[:type] = :local
43
+ end
44
+ end
45
+ end
46
+
47
+ def ignore_patch?(patch, paths: [], exclude_paths: [])
48
+ delta_new_file = patch.delta.new_file
49
+ args = [delta_new_file[:path], paths: paths, exclude_paths: exclude_paths]
50
+ if nested_git_repository_mode?(delta_new_file[:mode])
51
+ !ignore_directory?(*args)
52
+ else
53
+ !ignore_path?(*args)
54
+ end
55
+ end
56
+
57
+ def nested_git_repository_mode?(mode)
58
+ mode == 0o040000
59
+ end
60
+
61
+ def diff(from, to, **kwargs)
62
+ if from.nil? and to.nil?
63
+ mid_commit = latest_commit
64
+ diff_obj = super(nil, mid_commit, **kwargs)
65
+ diff_obj.merge! git.lookup(mid_commit).diff_workdir(**kwargs)
66
+ diff_obj
67
+ elsif to.nil?
68
+ git.lookup(from).diff_workdir(**kwargs)
69
+ else
70
+ super
71
+ end
72
+ end
73
+
74
+ def latest_commit(_branch = nil)
75
+ git.head.target_id
76
+ end
77
+
78
+ def lookup_commit(commit)
79
+ super
80
+ rescue Rugged::OdbError, TypeError => _e
81
+ raise Error::Rugged, code: :commit_not_found_in_local_git_repository, data: { commit: commit }
82
+ end
83
+
84
+ protected
85
+
86
+ def git_repo_exist?(path)
87
+ Rugged::Repository.new(path)
88
+ true
89
+ rescue Rugged::RepositoryError, Rugged::OSError => _e
90
+ false
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -1,63 +1,17 @@
1
1
  module Dapp
2
2
  module Dimg
3
3
  module GitRepo
4
- class Own < Base
4
+ class Own < Local
5
5
  def initialize(manager)
6
- super(manager, 'own')
6
+ super(manager, 'own', nil)
7
7
  end
8
8
 
9
- def exclude_paths
10
- dapp.local_git_artifact_exclude_paths
11
- end
12
-
13
- def workdir_path
14
- Pathname(git.workdir)
15
- end
16
-
17
- def path
18
- @path ||= Pathname(Rugged::Repository.discover(dapp.path.to_s).path)
19
- rescue Rugged::RepositoryError => _e
20
- raise Error::Rugged, code: :local_git_repository_does_not_exist
21
- end
22
-
23
- # NOTICE: Параметры {from: nil, to: nil} можно указать только для Own repo.
24
- # NOTICE: Для Remote repo такой вызов не имеет смысла и это ошибка пользователя класса Remote.
25
-
26
- def submodules_params(commit, paths: [], exclude_paths: [])
27
- return super unless commit.nil?
28
- return [] unless File.file?((gitmodules_file_path = File.join(workdir_path, '.gitmodules')))
29
-
30
- submodules_params_base(File.read(gitmodules_file_path), paths: paths, exclude_paths: exclude_paths)
31
- end
32
-
33
- def diff(from, to, **kwargs)
34
- if from.nil? and to.nil?
35
- mid_commit = latest_commit
36
- diff_obj = super(nil, mid_commit, **kwargs)
37
- diff_obj.merge! git.lookup(mid_commit).diff_workdir(**kwargs)
38
- diff_obj
39
- elsif to.nil?
40
- git.lookup(from).diff_workdir(**kwargs)
41
- else
42
- super
43
- end
44
- end
45
-
46
- def latest_commit(_branch = nil)
47
- git.head.target_id
9
+ def path=(_)
10
+ super(dapp.path.to_s)
48
11
  end
49
12
 
50
- def lookup_commit(commit)
51
- super
52
- rescue Rugged::OdbError, TypeError => _e
53
- raise Error::Rugged, code: :commit_not_found_in_local_git_repository, data: { commit: commit }
54
- end
55
-
56
- def exist?
57
- super
58
- rescue Error::Rugged => e
59
- return false if e.net_status[:code] == :local_git_repository_does_not_exist
60
- raise
13
+ def exclude_paths
14
+ dapp.local_git_artifact_exclude_paths
61
15
  end
62
16
  end
63
17
  end
@@ -27,7 +27,7 @@ module Dapp
27
27
  .reject { |job| ['0', 'false'].include? job.annotations["dapp/recreate"].to_s }
28
28
  .select { |job| all_jobs_names.include? job.name }
29
29
  .each do |job|
30
- log_process("Delete hooks job `#{job.name}`", short: true) do
30
+ log_process("Delete hook job `#{job.name}` (dapp/recreate)", short: true) do
31
31
  kube_delete_job!(job.name, all_pods_specs) unless dry_run?
32
32
  end
33
33
  end
@@ -133,13 +133,18 @@ module Dapp
133
133
  watch_hooks_condition.signal
134
134
  end
135
135
 
136
- release.deploy!
136
+ cmd_res = release.helm_upgrade!
137
+
138
+ if cmd_res.error?
139
+ raise ::Dapp::Error::Command, code: :kube_helm_failed, data: {output: (cmd_res.stdout + cmd_res.stderr).strip}
140
+ else
141
+ watch_hooks_thr.join if !dry_run? && watch_hooks_thr && watch_hooks_thr.alive?
142
+ log_info((cmd_res.stdout + cmd_res.stderr).strip)
143
+ end
137
144
  end
138
145
 
139
146
  deployment_managers.each(&:after_deploy)
140
147
 
141
- watch_hooks_thr.kill if !dry_run? && watch_hooks_thr && watch_hooks_thr.alive?
142
-
143
148
  unless dry_run?
144
149
  begin
145
150
  ::Timeout::timeout(self.options[:timeout] || 300) do
@@ -49,7 +49,7 @@ module Dapp
49
49
  end.to_h
50
50
  end
51
51
 
52
- def deploy!
52
+ def helm_upgrade!
53
53
  args = [
54
54
  name, chart_path, additional_values_options,
55
55
  set_options, upgrade_extra_options
@@ -57,7 +57,9 @@ module Dapp
57
57
 
58
58
  dapp.kubernetes.create_namespace!(namespace) unless dapp.kubernetes.namespace?(namespace)
59
59
 
60
- dapp.shellout! "helm upgrade #{args.join(' ')}", verbose: true
60
+ cmd = dapp.shellout "helm upgrade #{args.join(' ')}"
61
+
62
+ return cmd
61
63
  end
62
64
 
63
65
  def templates
@@ -63,7 +63,7 @@ module Dapp
63
63
  end
64
64
 
65
65
  dimgs = dapp.build_configs.map do |config|
66
- ::Dapp::Dimg::Dimg.new(config: config, dapp: dapp, ignore_git_fetch: true)
66
+ dapp.dimg(config: config, ignore_git_fetch: true)
67
67
  end.uniq do |dimg|
68
68
  dimg.config._name
69
69
  end
@@ -2,6 +2,20 @@ module Dapp
2
2
  module Kube
3
3
  module Kubernetes::Client::Resource
4
4
  class Pod < Base
5
+ # Returns:
6
+ # nil: no such condition yet
7
+ # "True" string: ready
8
+ # "False" string: not ready
9
+ def ready_condition_status
10
+ rd = self.ready_condition
11
+ return nil unless rd
12
+ return rd['status']
13
+ end
14
+
15
+ def ready_condition
16
+ status.fetch('conditions', {}).find {|condition| condition['type'] == 'Ready'}
17
+ end
18
+
5
19
  def container_id(container_name)
6
20
  container_status = spec.fetch('status', {})
7
21
  .fetch('containerStatuses')
@@ -18,7 +18,7 @@ module Dapp
18
18
  _, container_state_data = pod.container_state(name)
19
19
  return if @processed_containers_ids.include? container_state_data['containerID']
20
20
 
21
- pod_manager.wait_till_running!
21
+ pod_manager.wait_till_launched!
22
22
 
23
23
  pod = Kubernetes::Client::Resource::Pod.new(dapp.kubernetes.pod(pod_manager.name))
24
24
  container_state, container_state_data = pod.container_state(name)
@@ -22,6 +22,8 @@ module Dapp
22
22
  @deployment_before_deploy = Kubernetes::Client::Resource::Deployment.new(dapp.kubernetes.replace_deployment!(name, new_spec))
23
23
  end
24
24
  end
25
+
26
+ @deploy_began_at = Time.now
25
27
  end
26
28
 
27
29
  def after_deploy
@@ -116,7 +118,11 @@ module Dapp
116
118
  known_log_timestamps_by_pod_and_container[pod.name][container_name] ||= Set.new
117
119
 
118
120
  since_time = nil
119
- since_time = @deployed_at.utc.iso8601(9) if @deployed_at
121
+ # Если под еще не перешел в состоянии готовности, то можно вывести все логи которые имеются.
122
+ # Иначе выводим только новые логи с момента начала текущей сессии деплоя.
123
+ if [nil, "True"].include? pod.ready_condition_status
124
+ since_time = @deploy_began_at.utc.iso8601(9) if @deploy_began_at
125
+ end
120
126
 
121
127
  log_lines_by_time = []
122
128
  begin
@@ -147,34 +153,8 @@ module Dapp
147
153
  end
148
154
  end
149
155
 
150
- ready_condition = pod.status.fetch('conditions', {}).find {|condition| condition['type'] == 'Ready'}
151
- next if (not ready_condition) or (ready_condition['status'] == 'True')
152
-
153
- if ready_condition['reason'] == 'ContainersNotReady'
154
- Array(pod.status['containerStatuses']).each do |container_status|
155
- next if container_status['ready']
156
-
157
- waiting_reason = container_status.fetch('state', {}).fetch('waiting', {}).fetch('reason', nil)
158
- case waiting_reason
159
- when 'ImagePullBackOff', 'ErrImagePull'
160
- raise Kubernetes::Error::Base,
161
- code: :image_not_found,
162
- data: {pod_name: pod.name,
163
- reason: waiting_reason,
164
- message: container_status['state']['waiting']['message']}
165
- when 'CrashLoopBackOff'
166
- raise Kubernetes::Error::Base,
167
- code: :container_crash,
168
- data: {pod_name: pod.name,
169
- reason: waiting_reason,
170
- message: container_status['state']['waiting']['message']}
171
- end
172
- end
173
- else
174
- dapp.with_log_indent do
175
- dapp.log_warning("#{dapp.log_time}Unknown pod readiness condition reason '#{ready_condition['reason']}': #{ready_condition}", stream: dapp.service_stream)
176
- end
177
- end
156
+ pod_manager = Kubernetes::Manager::Pod.new(dapp, pod.name)
157
+ pod_manager.check_readiness_condition_if_available!(pod)
178
158
  end # with_log_indent
179
159
  end # rs_pods.each
180
160
  end # with_log_indent
@@ -9,10 +9,44 @@ module Dapp
9
9
  end
10
10
  end
11
11
 
12
- def wait_till_running!
12
+ def check_readiness_condition_if_available!(pod)
13
+ return if [nil, "True"].include? pod.ready_condition_status
14
+
15
+ if pod.ready_condition['reason'] == 'ContainersNotReady'
16
+ [*Array(pod.status["initContainerStatuses"]), *Array(pod.status["containerStatuses"])].each do |container_status|
17
+ next if container_status['ready']
18
+
19
+ waiting_reason = container_status.fetch('state', {}).fetch('waiting', {}).fetch('reason', nil)
20
+ case waiting_reason
21
+ when 'ImagePullBackOff', 'ErrImagePull'
22
+ raise Kubernetes::Error::Default,
23
+ code: :bad_image,
24
+ data: {pod_name: pod.name,
25
+ reason: waiting_reason,
26
+ message: container_status['state']['waiting']['message']}
27
+ when 'CrashLoopBackOff'
28
+ raise Kubernetes::Error::Default,
29
+ code: :container_crash,
30
+ data: {pod_name: pod.name,
31
+ reason: waiting_reason,
32
+ message: container_status['state']['waiting']['message']}
33
+ end
34
+ end
35
+ else
36
+ dapp.with_log_indent do
37
+ dapp.log_warning("#{dapp.log_time}Unknown pod readiness condition reason '#{pod.ready_condition['reason']}': #{pod.ready_condition}", stream: dapp.service_stream)
38
+ end
39
+ end
40
+ end
41
+
42
+ def wait_till_launched!
13
43
  loop do
14
44
  pod = Kubernetes::Client::Resource::Pod.new(dapp.kubernetes.pod(name))
15
- break if pod.phase == 'Running'
45
+
46
+ break if pod.phase != "Pending"
47
+
48
+ check_readiness_condition_if_available!(pod)
49
+
16
50
  sleep 0.1
17
51
  end
18
52
  end
@@ -1,4 +1,4 @@
1
1
  module Dapp
2
- VERSION = "0.24.3"
2
+ VERSION = "0.24.4"
3
3
  BUILD_CACHE_VERSION = 26
4
4
  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.24.3
4
+ version: 0.24.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitry Stolyarov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-18 00:00:00.000000000 Z
11
+ date: 2018-01-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mixlib-shellout
@@ -600,6 +600,7 @@ files:
600
600
  - lib/dapp/dimg/dapp/command/tag.rb
601
601
  - lib/dapp/dimg/dapp/dapp.rb
602
602
  - lib/dapp/dimg/dapp/dappfile.rb
603
+ - lib/dapp/dimg/dapp/dimg.rb
603
604
  - lib/dapp/dimg/dimg.rb
604
605
  - lib/dapp/dimg/dimg/git_artifact.rb
605
606
  - lib/dapp/dimg/dimg/path.rb
@@ -624,6 +625,7 @@ files:
624
625
  - lib/dapp/dimg/filelock.rb
625
626
  - lib/dapp/dimg/git_artifact.rb
626
627
  - lib/dapp/dimg/git_repo/base.rb
628
+ - lib/dapp/dimg/git_repo/local.rb
627
629
  - lib/dapp/dimg/git_repo/own.rb
628
630
  - lib/dapp/dimg/git_repo/remote.rb
629
631
  - lib/dapp/dimg/image/argument.rb