dapp 0.25.8 → 0.26.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fce0f6b6791bf4fba6bd882e3563b1b57272f452
4
- data.tar.gz: 344cfd21cf25a679ba1176b785ce2122d4673bcb
3
+ metadata.gz: f76da5bbcfb8d6dfe619a3070e565706c5fe3687
4
+ data.tar.gz: a3d24e6ac82d6112decf07c48e9fdf6aafcafab0
5
5
  SHA512:
6
- metadata.gz: fb9f90a3add54f6f4ec82490de02f9a47355af1ba91af60b50bc8b67fe9e394ae0a33e5a4e0c88ee08809d6fe56928f266756964097f6957ed964f5476f25ac8
7
- data.tar.gz: 2901374544207c428ce7dd926cc0760d195784a7a6338c0dbefe5833bd2b758ae1c4904d8c273ca8b14d227054310fdc899c3654a38c0b7f2dc6edf2db0f6874
6
+ metadata.gz: 361cf09b363732b5adde9a230e8f0ec895508067a34e6f41bb47a8daacacc35245b0328471230fd0c27767258dfa8d07f14f4b09ef03c1df506bac9b47481cdb
7
+ data.tar.gz: a25004f9b889e24acd5ce052c8565c1510f0eab6faaea03e36406077e763d3e8c676dfeae4002ea0fb396bf39ee11da8988652daeb4867bf581f4c1eb2faff8f
data/bin/dapp CHANGED
@@ -28,10 +28,6 @@ begin
28
28
  $stderr.puts "\033[1m\033[90mStacktrace dumped to #{filename}\033[0m"
29
29
  end
30
30
 
31
- if Dapp::CLI.dapp_object
32
- Dapp::CLI.dapp_object.sentry_exception(e)
33
- end
34
-
35
31
  raise
36
32
  end
37
33
  rescue Dapp::Error::Shellout => e
data/config/en/common.yml CHANGED
@@ -61,7 +61,6 @@ en:
61
61
  introspect_image_impossible: "WARNING: You can't introspect stage `%{name}`!"
62
62
  stage_dependencies_not_found: "WARNING: Stage dependencies `%{dependencies}` haven't been found in repo `%{repo}`!"
63
63
  unsupported_dapp_config_options: "WARNING: .dapp_config includes unsupported options [%{options}]: use only following options [%{supported_options}]"
64
- secret_key_dappfile_not_found: "WARNING: Project root directory can't be initialized: Dappfile not found!"
65
64
  group:
66
65
  install: 'Install group'
67
66
  setup: 'Setup group'
@@ -48,7 +48,7 @@ en:
48
48
  dapp:
49
49
  no_such_dimg: "No such dimg: `%{dimgs_patterns}`!"
50
50
  no_such_app: "No such app: `%{apps_patterns}`!"
51
- dappfile_not_found: "Dappfile not found!"
51
+ dappfile_not_found: "dappfile.yml, dappfile.yaml or Dappfile not found!"
52
52
  cannot_run_ssh_agent: "Can't run ssh-agent!"
53
53
  ssh_key_not_found: "Ssh key `%{path}` doesn't exist!"
54
54
  docker_not_found: "Docker not found!"
@@ -60,6 +60,7 @@ en:
60
60
  incorrect_dapp_config_option_color: ".dapp_config includes option `color` with incorrect value `%{value}`: expected one of the following values [%{expected}]"
61
61
  ci_environment_required: 'CI environment required (Travis or GitLab CI)!'
62
62
  git_branch_without_name: "Dimg has specific revision that isn't associated with a branch name!"
63
+ download_failed_bad_dappfile_yml_checksum: "Cannot download dappfile-yml binary dependency from %{url}: checksum validation failed"
63
64
  config:
64
65
  dimg_name_required: 'Dimg name required!'
65
66
  dimg_name_incorrect: "Dimg has incorrect name `%{value}`: doesn't match regex `%{pattern}`!"
data/lib/dapp.rb CHANGED
@@ -26,8 +26,8 @@ require 'zlib'
26
26
  require 'slugify'
27
27
  require 'base64'
28
28
  require 'io/console'
29
- require 'sentry-raven'
30
- require 'toml-rb'
29
+ require 'net/http'
30
+ require 'progressbar'
31
31
 
32
32
  require 'dapp/version'
33
33
  require 'dapp/core_ext/hash'
@@ -38,7 +38,6 @@ require 'dapp/helper/sha256'
38
38
  require 'dapp/helper/net_status'
39
39
  require 'dapp/helper/tar'
40
40
  require 'dapp/helper/yaml'
41
- require 'dapp/helper/url'
42
41
  require 'dapp/prctl'
43
42
  require 'dapp/error/mod/user'
44
43
  require 'dapp/error/base'
@@ -59,7 +58,6 @@ require 'dapp/config/directive/base'
59
58
  require 'dapp/config/config'
60
59
  require 'dapp/dapp/lock'
61
60
  require 'dapp/dapp/ssh_agent'
62
- require 'dapp/dapp/sentry'
63
61
  require 'dapp/dapp/git_artifact'
64
62
  require 'dapp/dapp/dappfile'
65
63
  require 'dapp/dapp/chef'
@@ -273,6 +271,7 @@ require 'dapp/dimg/dimg/path'
273
271
  require 'dapp/dimg/dimg/stages'
274
272
  require 'dapp/dimg/dimg'
275
273
  require 'dapp/dimg/artifact'
274
+ require 'dapp/downloader'
276
275
 
277
276
  module Dapp
278
277
  def self.root
data/lib/dapp/cli.rb CHANGED
@@ -38,10 +38,6 @@ BANNER
38
38
  show_options: true,
39
39
  exit: 0
40
40
 
41
- class << self
42
- attr_accessor :dapp_object
43
- end
44
-
45
41
  def initialize(*args)
46
42
  super(*args)
47
43
 
@@ -58,8 +58,6 @@ module Dapp
58
58
 
59
59
  def run_dapp_command(run_method, options: {}, log_running_time: true, try_host_docker_login: false)
60
60
  dapp = ::Dapp::Dapp.new(options: options)
61
- ::Dapp::CLI.dapp_object = dapp
62
- dapp.sentry_message("Manual usage: `#{options[:dapp_command]}` command") unless ENV['CI']
63
61
 
64
62
  log_dapp_running_time(dapp, ignore: !log_running_time) do
65
63
  begin
@@ -76,10 +74,6 @@ module Dapp
76
74
  end
77
75
  end
78
76
 
79
- def run_method
80
- class_to_lowercase
81
- end
82
-
83
77
  def log_dapp_running_time(dapp, ignore: false)
84
78
  return yield if ignore
85
79
 
@@ -101,7 +95,7 @@ module Dapp
101
95
  self.class.print_error_with_help_and_die! self, "cannot use alias options --run-dir, --build-dir, --deploy-dir at the same time"
102
96
  end
103
97
 
104
- config.merge(build_dir: dirs.compact.first, dapp_command: run_method, **kwargs)
98
+ config.merge(build_dir: dirs.compact.first, **kwargs)
105
99
  end
106
100
  end
107
101
  end
@@ -12,6 +12,13 @@ module Dapp
12
12
  _clone
13
13
  end
14
14
 
15
+ def encode_with(coder)
16
+ (instance_variables - [:@dapp]).each do |var|
17
+ var = var.to_s
18
+ coder[var.gsub('@', '')] = instance_variable_get(var)
19
+ end
20
+ end
21
+
15
22
  protected
16
23
 
17
24
  attr_reader :dapp
data/lib/dapp/dapp.rb CHANGED
@@ -17,13 +17,10 @@ module Dapp
17
17
  include Logging::Paint
18
18
 
19
19
  include SshAgent
20
- include Sentry
21
-
22
20
  include Helper::Sha256
23
- extend Helper::Trivia
21
+ extend Helper::Trivia
24
22
  include Helper::Trivia
25
23
  include Helper::Tar
26
- include Helper::Url
27
24
 
28
25
  include Deps::Toolchain
29
26
  include Deps::Gitartifact
@@ -46,18 +43,6 @@ module Dapp
46
43
  self.class.options
47
44
  end
48
45
 
49
- def settings
50
- @settings ||= begin
51
- settings_path = File.join(self.class.home_dir, "settings.toml")
52
-
53
- if File.exists? settings_path
54
- TomlRB.load_file(settings_path)
55
- else
56
- {}
57
- end
58
- end
59
- end
60
-
61
46
  def name
62
47
  @name ||= begin
63
48
  n = begin
@@ -98,8 +83,12 @@ module Dapp
98
83
  nil
99
84
  end
100
85
 
86
+ def work_dir
87
+ File.expand_path(options[:dir] || Dir.pwd)
88
+ end
89
+
101
90
  def path(*path)
102
- @path ||= expand_path(dappfile_path)
91
+ @path ||= make_path(work_dir)
103
92
  make_path(@path, *path)
104
93
  end
105
94
 
@@ -107,8 +96,8 @@ module Dapp
107
96
  self.class.tmp_base_dir
108
97
  end
109
98
 
110
- def build_dir
111
- @build_dir ||= begin
99
+ def build_path(*path)
100
+ @build_path ||= begin
112
101
  if option_build_dir
113
102
  Pathname.new(option_build_dir)
114
103
  else
@@ -116,10 +105,7 @@ module Dapp
116
105
  Pathname.new(dir)
117
106
  end.expand_path.tap(&:mkpath)
118
107
  end
119
- end
120
-
121
- def build_path(*path)
122
- make_path(build_dir, *path)
108
+ make_path(@build_path, *path)
123
109
  end
124
110
 
125
111
  def local_git_artifact_exclude_paths(&blk)
@@ -1,58 +1,150 @@
1
1
  module Dapp
2
2
  class Dapp
3
3
  module Dappfile
4
+ module Error
5
+ class DappfileYmlErrorResponse < ::Dapp::Error::Default
6
+ def initialize(error_code, response)
7
+ net_status = {}
8
+ net_status[:code] = error_code
9
+ net_status[:message] = response["message"] if response["message"]
10
+ super(net_status)
11
+ end
12
+ end
13
+ end
14
+
4
15
  def local_git_artifact_exclude_paths(&blk)
5
16
  super do |exclude_paths|
6
17
  exclude_paths << 'Dappfile'
18
+ exclude_paths << "dappfile.yml"
19
+ exclude_paths << "dappfile.yaml"
7
20
 
8
21
  yield exclude_paths if block_given?
9
22
  end
10
23
  end
11
24
 
12
- def dappfile_exists?
13
- !!search_file_upward('Dappfile')
14
- end
15
-
16
- def dappfile_path
17
- raise Error::Dapp, code: :dappfile_not_found unless (dappfile_path = search_file_upward('Dappfile'))
18
- dappfile_path
19
- end
20
-
21
- def work_dir
22
- File.expand_path(options[:dir] || Dir.pwd)
23
- end
24
-
25
25
  def expand_path(path, number = 1)
26
26
  path = File.expand_path(path)
27
27
  number.times.each { path = File.dirname(path) }
28
28
  path
29
29
  end
30
30
 
31
+ def dappfile_exists?
32
+ File.exist?(path("dappfile.yml")) ||
33
+ File.exist?(path("dappfile.yaml")) ||
34
+ File.exist?(path("Dappfile")) ||
35
+ ENV["DAPP_LOAD_CONFIG_PATH"]
36
+ end
37
+
31
38
  def config
32
39
  @config ||= begin
33
- ::Dapp::Config::Config.new(dapp: self).tap do |config|
34
- begin
35
- config.instance_eval File.read(dappfile_path), dappfile_path
36
- config.after_parsing!
37
- config.validate!
38
- rescue SyntaxError, StandardError => e
39
- backtrace = e.backtrace.find { |line| line.start_with?(dappfile_path) }
40
- message = begin
41
- case e
42
- when NoMethodError
43
- e.message =~ /`.*'/
44
- "undefined method #{Regexp.last_match}"
45
- when NameError then e.message[/.*(?= for)/]
46
- else
47
- e.message
48
- end
40
+ config = nil
41
+
42
+ dappfile_yml = path("dappfile.yml").to_s
43
+ dappfile_yaml = path("dappfile.yaml").to_s
44
+ dappfile_ruby = path("Dappfile").to_s
45
+
46
+ if ENV["DAPP_LOAD_CONFIG_PATH"]
47
+ config = YAML.load_file ENV["DAPP_LOAD_CONFIG_PATH"]
48
+ elsif File.exist? dappfile_yml
49
+ config = load_dappfile_yml(dappfile_yml)
50
+ elsif File.exist? dappfile_yaml
51
+ config = load_dappfile_yml(dappfile_yaml)
52
+ elsif File.exist? dappfile_ruby
53
+ config = load_dappfile_ruby(dappfile_ruby)
54
+ else
55
+ raise ::Dapp::Error::Dapp, code: :dappfile_not_found
56
+ end
57
+
58
+ if ENV["DAPP_DUMP_CONFIG"]
59
+ puts "-- DAPP_DUMP_CONFIG BEGIN"
60
+ puts YAML.dump(config)
61
+ puts "-- DAPP_DUMP_CONFIG END"
62
+ end
63
+
64
+ config
65
+ end # begin
66
+ end
67
+
68
+ def load_dappfile_ruby(dappfile_path)
69
+ ::Dapp::Config::Config.new(dapp: self).tap do |config|
70
+ begin
71
+ config.instance_eval File.read(dappfile_path), dappfile_path
72
+ config.after_parsing!
73
+ config.validate!
74
+ rescue SyntaxError, StandardError => e
75
+ backtrace = e.backtrace.find { |line| line.start_with?(dappfile_path) }
76
+ message = begin
77
+ case e
78
+ when NoMethodError
79
+ e.message =~ /`.*'/
80
+ "undefined method #{Regexp.last_match}"
81
+ when NameError then e.message[/.*(?= for)/]
82
+ else
83
+ e.message
49
84
  end
50
- message = "#{backtrace[/.*(?=:in)/]}: #{message}" if backtrace
51
- raise Error::Dappfile, code: :incorrect, data: { error: e.class.name, message: message }
52
85
  end
86
+ message = "#{backtrace[/.*(?=:in)/]}: #{message}" if backtrace
87
+ raise ::Dapp::Error::Dappfile, code: :incorrect, data: { error: e.class.name, message: message }
88
+ end # begin-rescue
89
+ end
90
+ end
91
+
92
+ def load_dappfile_yml(dappfile_path)
93
+ if dappfile_yml_bin_path = ENV["DAPP_BIN_DAPPFILE_YML"]
94
+ unless File.exists? dappfile_yml_bin_path
95
+ raise ::Dapp::Error::Dapp, code: :dappfile_yml_bin_path_not_found, data: {path: dappfile_yml_bin_path}
96
+ end
97
+ else
98
+ dappfile_yml_bin_path = File.join(::Dapp::Dapp.home_dir, "bin", "dappfile-yml", ::Dapp::VERSION, "dappfile-yml")
99
+ unless File.exists? dappfile_yml_bin_path
100
+ download_dappfile_yml_bin(dappfile_yml_bin_path)
53
101
  end
54
102
  end
103
+
104
+ cmd_res = shellout "#{dappfile_yml_bin_path} -dappfile #{dappfile_path}"
105
+
106
+ raw_json_response = nil
107
+ if cmd_res.exitstatus == 0
108
+ raw_json_response = cmd_res.stdout
109
+ elsif cmd_res.exitstatus == 16
110
+ raw_json_response = cmd_res.stderr
111
+ else
112
+ shellout_cmd_should_succeed! cmd_res
113
+ end
114
+
115
+ response = JSON.parse(raw_json_response)
116
+
117
+ raise ::Dapp::Dapp::Error::DappfileYmlErrorResponse.new(response["error"], response) if response["error"]
118
+
119
+ YAML.load response["dappConfig"]
120
+ end
121
+
122
+ def download_dappfile_yml_bin(dappfile_yml_bin_path)
123
+ lock("downloader.bin.dappfile-yml", default_timeout: 1800) do
124
+ return if File.exists? dappfile_yml_bin_path
125
+
126
+ log_process("Downloading dappfile-yml dapp dependency") do
127
+ # FIXME use flant repo
128
+ location = URI("https://dl.bintray.com/diafour/dapp/#{::Dapp::VERSION}/dappfile-yml")
129
+
130
+ tmp_bin_path = File.join(self.class.tmp_base_dir, "dappfile-yml-#{SecureRandom.uuid}")
131
+ ::Dapp::Downloader.download(location, tmp_bin_path, show_progress: true, progress_titile: dappfile_yml_bin_path)
132
+
133
+ checksum_location = URI("https://dl.bintray.com/diafour/dapp/#{::Dapp::VERSION}/dappfile-yml.sha")
134
+ tmp_bin_checksum_path = tmp_bin_path + ".checksum"
135
+ ::Dapp::Downloader.download(checksum_location, tmp_bin_checksum_path)
136
+
137
+ if Digest::SHA256.hexdigest(File.read(tmp_bin_path)) != File.read(tmp_bin_checksum_path).strip
138
+ raise ::Dapp::Error::Dapp, code: :download_failed_bad_dappfile_yml_checksum, data: {url: location.to_s, checksum_url: checksum_location.to_s}
139
+ end
140
+
141
+ File.chmod(0755, tmp_bin_path)
142
+ FileUtils.mkdir_p File.dirname(dappfile_yml_bin_path)
143
+ FileUtils.mv tmp_bin_path, dappfile_yml_bin_path
144
+ end # log_process
145
+ end # lock
55
146
  end
147
+
56
148
  end # Dappfile
57
149
  end # Dapp
58
150
  end # Dapp
@@ -7,12 +7,6 @@ module Dapp
7
7
 
8
8
  def tags_by_scheme
9
9
  @tags_by_scheme_name ||= begin
10
- if slug_tags[:custom].any?
11
- if settings.fetch("sentry", {}).fetch("detect-push-tag-usage", false)
12
- sentry_message("--tag or --tag-slug usage detected", extra: {"slug_tags" => slug_tags})
13
- end
14
- end
15
-
16
10
  {}.tap do |tags_by_scheme|
17
11
  [slug_tags, branch_tags, ci_tags].each do |_tags_by_scheme|
18
12
  _tags_by_scheme.each do |scheme, tags|
@@ -95,4 +89,4 @@ module Dapp
95
89
  end
96
90
  end # Tags
97
91
  end # Dapp
98
- end # Dapp
92
+ end # Dapp
@@ -189,10 +189,8 @@ module Dapp
189
189
  commits[git_artifact] ||= begin
190
190
  if image.built?
191
191
  image.labels[dimg.dapp.dimgstage_g_a_commit_label(git_artifact.paramshash)]
192
- elsif g_a_stage? && !empty?
192
+ else
193
193
  git_artifact.latest_commit
194
- elsif prev_stage
195
- prev_stage.layer_commit(git_artifact)
196
194
  end
197
195
  end
198
196
  end
@@ -10,7 +10,7 @@ module Dapp
10
10
  image.add_volume "#{dimg.tmp_path('patches')}:#{dimg.container_tmp_path('patches')}:ro"
11
11
 
12
12
  dimg.git_artifacts.each do |git_artifact|
13
- image.add_service_change_label(dimg.dapp.dimgstage_g_a_commit_label(git_artifact.paramshash).to_sym => layer_commit(git_artifact))
13
+ image.add_service_change_label(dimg.dapp.dimgstage_g_a_commit_label(git_artifact.paramshash).to_sym => git_artifact.latest_commit)
14
14
  image.add_command git_artifact.send(apply_command_method, self)
15
15
  end
16
16
  end
@@ -28,9 +28,7 @@ module Dapp
28
28
  private
29
29
 
30
30
  def commit_list
31
- dimg.git_artifacts
32
- .select { |ga| ga.repo.commit_exists?(prev_stage.layer_commit(ga)) && ga.patch_any_changes?(self) }
33
- .map(&method(:layer_commit))
31
+ dimg.git_artifacts.map { |git_artifact| layer_commit(git_artifact) }
34
32
  end
35
33
 
36
34
  def git_artifacts_dev_patch_hashes
@@ -9,6 +9,10 @@ module Dapp::Dimg::CLI
9
9
  self.class.parse_options(self, argv)
10
10
  run_dapp_command(run_method, options: cli_options(dimgs_patterns: cli_arguments))
11
11
  end
12
+
13
+ def run_method
14
+ class_to_lowercase
15
+ end
12
16
  end
13
17
  end
14
18
  end
@@ -4,8 +4,6 @@ module Dapp
4
4
  module Directive
5
5
  class Dimg < Base
6
6
  module Validation
7
- include Helper::Trivia
8
-
9
7
  def validate!
10
8
  directives_validate!
11
9
  validate_scratch!
@@ -140,13 +138,29 @@ module Dapp
140
138
  end
141
139
 
142
140
  def validate_artifact!(verifiable_artifact, artifact)
143
- cases = []
144
- cases << verifiable_artifact[:include_paths].any? do |verifiable_path|
145
- !ignore_path?(verifiable_path, paths: artifact[:include_paths], exclude_paths: artifact[:exclude_paths])
141
+ verifiable_artifact[:include_paths].each do |verifiable_path|
142
+ potential_conflicts = artifact[:include_paths].select { |path| path.start_with?(verifiable_path) }
143
+ validate_artifact_path!(verifiable_artifact, potential_conflicts)
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
146
152
  end
147
- cases << (verifiable_artifact[:include_paths].empty? && artifact[:include_paths].empty?)
153
+ end
148
154
 
149
- raise ::Dapp::Error::Config, code: :artifact_conflict if cases.any?
155
+ def validate_artifact_path!(verifiable_artifact, potential_conflicts)
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)
162
+ end
163
+ end
150
164
  end
151
165
 
152
166
  def _associated_artifacts
@@ -3,13 +3,14 @@ module Dapp
3
3
  module Config
4
4
  module Directive
5
5
  class GitArtifactRemote < GitArtifactLocal
6
- include ::Dapp::Helper::Url
7
-
8
6
  attr_reader :_url, :_name, :_branch, :_commit
9
7
 
10
8
  def initialize(url, **kwargs, &blk)
11
9
  @_url = url
12
- @_name = git_url_to_name(url)
10
+
11
+ url_without_scheme = url.split("://", 2).last
12
+ url_without_creds = url_without_scheme.split(":", 2).last
13
+ @_name = url_without_creds.gsub(%r{.*?([^\/ ]+\/[^\/ ]+)\.git}, '\\1')
13
14
 
14
15
  super(**kwargs, &blk)
15
16
  end
@@ -189,8 +189,6 @@ module Dapp
189
189
  end
190
190
 
191
191
  def cleanup_tmp
192
- return unless tmp_dir_exists?
193
-
194
192
  # В tmp-директории могли остаться файлы, владельцами которых мы не являемся.
195
193
  # Такие файлы могут попасть туда при экспорте файлов артефакта.
196
194
  # Чтобы от них избавиться — запускаем docker-контейнер под root-пользователем
@@ -6,10 +6,6 @@ module Dapp
6
6
  dapp.path(*path).expand_path
7
7
  end
8
8
 
9
- def tmp_dir_exists?
10
- @tmp_path != nil
11
- end
12
-
13
9
  def tmp_path(*path)
14
10
  @tmp_path ||= Dir.mktmpdir('dapp-', dapp.tmp_base_dir)
15
11
  make_path(@tmp_path, *path).expand_path.tap { |p| p.parent.mkpath }
@@ -35,6 +35,7 @@ module Dapp
35
35
  end
36
36
 
37
37
  def image_delete(tag)
38
+ image_blobs(tag).each { |hash| blob_delete(hash.values.first) }
38
39
  api_request(repo_suffix, "/manifests/#{image_digest(tag)}",
39
40
  method: :delete,
40
41
  expects: [202, 404],
@@ -53,6 +54,10 @@ module Dapp
53
54
  headers: { Accept: 'application/vnd.docker.distribution.manifest.v2+json' }).headers['Docker-Content-Digest']
54
55
  end
55
56
 
57
+ def image_blobs(tag)
58
+ manifest_v1(tag)['fsLayers']
59
+ end
60
+
56
61
  def manifest_v1(tag)
57
62
  api_request(repo_suffix, "/manifests/#{tag}")
58
63
  end
@@ -62,6 +67,11 @@ module Dapp
62
67
  headers: { Accept: 'application/vnd.docker.distribution.manifest.v2+json' })
63
68
  end
64
69
 
70
+ def blob_delete(id)
71
+ api_request(repo_suffix, "/blobs/#{id}",
72
+ method: :delete, expects: [202, 404])
73
+ end
74
+
65
75
  def api_request(*uri, **options)
66
76
  JSON.load(raw_api_request(*uri, **options).body)
67
77
  end
@@ -121,7 +121,7 @@ module Dapp
121
121
  last_part_path = path_parts.shift
122
122
  test_path = [test_path, last_part_path].compact.join('/')
123
123
 
124
- non_match = !File.fnmatch(test_path, embedded_rel_path, File::FNM_PATHNAME|File::FNM_DOTMATCH)
124
+ non_match = !File.fnmatch(test_path, embedded_rel_path, File::FNM_PATHNAME)
125
125
  part_for_all = (last_part_path == '**')
126
126
 
127
127
  if non_match || part_for_all
@@ -104,12 +104,12 @@ module Dapp
104
104
 
105
105
  def patches(from, to, paths: [], exclude_paths: [], **kwargs)
106
106
  diff(from, to, **kwargs).patches.select do |patch|
107
- !ignore_patch?(patch, paths: paths, exclude_paths: exclude_paths)
107
+ ignore_patch?(patch, paths: paths, exclude_paths: exclude_paths)
108
108
  end
109
109
  end
110
110
 
111
111
  def ignore_patch?(patch, paths: [], exclude_paths: [])
112
- ignore_path?(patch.delta.new_file[:path], paths: paths, exclude_paths: exclude_paths)
112
+ !ignore_path?(patch.delta.new_file[:path], paths: paths, exclude_paths: exclude_paths)
113
113
  end
114
114
 
115
115
  def entries(commit, paths: [], exclude_paths: [])
@@ -227,6 +227,22 @@ module Dapp
227
227
  paths.empty? || paths.any? { |p| check_path?(path, p) || check_subpath?(path, p) }
228
228
  end
229
229
  end
230
+
231
+ def ignore_path?(path, paths: [], exclude_paths: [])
232
+ ignore_path_base(path, exclude_paths: exclude_paths) do
233
+ paths.empty? ||
234
+ paths.any? do |p|
235
+ File.fnmatch?(p, path, File::FNM_PATHNAME) ||
236
+ File.fnmatch?(File.join(p, '**', '*'), path, File::FNM_PATHNAME)
237
+ end
238
+ end
239
+ end
240
+
241
+ def ignore_path_base(path, exclude_paths: [])
242
+ is_exclude_path = exclude_paths.any? { |p| check_path?(path, p) }
243
+ is_include_path = yield
244
+ is_exclude_path || !is_include_path
245
+ end
230
246
  end
231
247
  end
232
248
  end
@@ -48,9 +48,9 @@ module Dapp
48
48
  delta_new_file = patch.delta.new_file
49
49
  args = [delta_new_file[:path], paths: paths, exclude_paths: exclude_paths]
50
50
  if nested_git_repository_mode?(delta_new_file[:mode])
51
- ignore_directory?(*args)
51
+ !ignore_directory?(*args)
52
52
  else
53
- ignore_path?(*args)
53
+ !ignore_path?(*args)
54
54
  end
55
55
  end
56
56
 
@@ -0,0 +1,117 @@
1
+ module Dapp
2
+ module Downloader
3
+ module Error
4
+ class DownloadFailed < ::Exception
5
+ end
6
+ end
7
+
8
+ class BytesCount
9
+ attr_reader :bytes, :total_bytes_count
10
+
11
+ def initialize(bytes, total_bytes_count: nil)
12
+ @bytes = bytes.to_f
13
+ @total_bytes_count = total_bytes_count
14
+ end
15
+
16
+ def to_s(*a)
17
+ max_bytes = @total_bytes_count || self
18
+ width = sprintf("%.2f", max_bytes.bytes/1024/1024).bytesize
19
+ sprintf("%#{width}.2f", @bytes/1024/1024)
20
+ end
21
+
22
+ [:+, :-, :*, :/].each do |method|
23
+ define_method(method) do |arg|
24
+ res = case arg
25
+ when BytesCount
26
+ @bytes.send(method, arg.bytes)
27
+ else
28
+ @bytes.send(method, arg)
29
+ end
30
+ self.class.new(res, total_bytes_count: total_bytes_count)
31
+ end
32
+ end
33
+
34
+ [:>, :<, :==].each do |method|
35
+ define_method(method) do |arg|
36
+ case arg
37
+ when BytesCount
38
+ @bytes.send(method, arg.bytes)
39
+ else
40
+ @bytes.send(method, arg)
41
+ end
42
+ end
43
+ end
44
+
45
+ def method_missing(method, *args, &blk)
46
+ case method
47
+ when :to_f, :to_i
48
+ @bytes.send(method, *args, &blk)
49
+ else
50
+ raise
51
+ end
52
+ end
53
+ end # BytesCount
54
+
55
+ class << self
56
+ def download(url, destination, show_progress: false, progress_titile: nil)
57
+ resp = nil
58
+ location = URI(url)
59
+ done = false
60
+ state = {}
61
+
62
+ loop do
63
+ Net::HTTP.start(location.host, location.port, use_ssl: true) do |http|
64
+ req = Net::HTTP::Get.new location
65
+ http.request req do |resp|
66
+ case resp
67
+ when Net::HTTPRedirection
68
+ location = URI(resp["location"])
69
+ next
70
+ when Net::HTTPSuccess
71
+ File.open(destination, "wb") do |file|
72
+ file_size_bytes = nil
73
+ file_size_bytes = BytesCount.new(resp.to_hash["content-length"].first.to_f) if show_progress
74
+
75
+ if show_progress
76
+ old_DEFAULT_BEGINNING_POSITION = ProgressBar::Progress.send(:remove_const, :DEFAULT_BEGINNING_POSITION)
77
+ ProgressBar::Progress.send(:const_set, :DEFAULT_BEGINNING_POSITION, BytesCount.new(0, total_bytes_count: file_size_bytes))
78
+ end
79
+
80
+ begin
81
+ progressbar = nil
82
+ progressbar = ProgressBar.create(
83
+ format: " %cMB / %CMB %B %t",
84
+ starting_at: BytesCount.new(0, total_bytes_count: file_size_bytes),
85
+ total: file_size_bytes,
86
+ progress_mark: "#",
87
+ remainder_mark: ".",
88
+ title: progress_titile,
89
+ length: 100,
90
+ autofinish: true
91
+ ) if show_progress
92
+
93
+ resp.read_body do |segment|
94
+ progressbar.progress = progressbar.progress + segment.bytesize if show_progress
95
+ file.write segment
96
+ end
97
+ ensure
98
+ if show_progress
99
+ ProgressBar::Progress.send(:remove_const, :DEFAULT_BEGINNING_POSITION)
100
+ ProgressBar::Progress.send(:const_set, :DEFAULT_BEGINNING_POSITION, old_DEFAULT_BEGINNING_POSITION)
101
+ end
102
+ end
103
+ end # File.open
104
+
105
+ done = true
106
+ else
107
+ raise Error::DownloadFailed, "Failed to download #{url}: #{resp.code} #{resp.message}"
108
+ end # when
109
+ end # http.request
110
+ end # Net::HTTP.start
111
+
112
+ break if done
113
+ end # loop
114
+ end
115
+ end
116
+ end # Downloader
117
+ end # Dapp
@@ -28,28 +28,12 @@ module Dapp
28
28
  Pathname.new(File.join(base.to_s, *path.compact.map(&:to_s)))
29
29
  end
30
30
 
31
- def ignore_path?(path, paths: [], exclude_paths: [])
32
- ignore_path_base(path, exclude_paths: exclude_paths) do
33
- paths.empty? ||
34
- paths.any? do |p|
35
- File.fnmatch?(p, path, File::FNM_PATHNAME|File::FNM_DOTMATCH) ||
36
- File.fnmatch?(File.join(p, '**', '*'), path, File::FNM_PATHNAME|File::FNM_DOTMATCH)
37
- end
38
- end
39
- end
40
-
41
- def ignore_path_base(path, exclude_paths: [])
42
- is_exclude_path = exclude_paths.any? { |p| check_path?(path, p) }
43
- is_include_path = yield
44
- is_exclude_path || !is_include_path
45
- end
46
-
47
31
  def check_path?(path, format)
48
- path_checker(path) { |checking_path| File.fnmatch(format, checking_path, File::FNM_PATHNAME|File::FNM_DOTMATCH) }
32
+ path_checker(path) { |checking_path| File.fnmatch(format, checking_path, File::FNM_PATHNAME) }
49
33
  end
50
34
 
51
35
  def check_subpath?(path, format)
52
- path_checker(format) { |checking_path| File.fnmatch(checking_path, path, File::FNM_PATHNAME|File::FNM_DOTMATCH) }
36
+ path_checker(format) { |checking_path| File.fnmatch(checking_path, path, File::FNM_PATHNAME) }
53
37
  end
54
38
 
55
39
  def path_checker(path)
@@ -321,15 +321,11 @@ image: {{ tuple $name $context | include "_dimg2" }}
321
321
  unless (secret_key = ENV['DAPP_SECRET_KEY'])
322
322
  secret_key_not_found_in << '`DAPP_SECRET_KEY`'
323
323
 
324
- if dappfile_exists?
325
- file_path = path('.dapp_secret_key')
326
- if file_path.file?
327
- secret_key = path('.dapp_secret_key').read.chomp
328
- else
329
- secret_key_not_found_in << "`#{file_path}`"
330
- end
324
+ file_path = path('.dapp_secret_key')
325
+ if file_path.file?
326
+ secret_key = path('.dapp_secret_key').read.chomp
331
327
  else
332
- log_warning(desc: { code: :secret_key_dappfile_not_found })
328
+ secret_key_not_found_in << "`#{file_path}`"
333
329
  end
334
330
  end
335
331
 
@@ -162,7 +162,6 @@ module Dapp
162
162
  # Поэтому перехватываем и просто отображаем произошедшую
163
163
  # ошибку для информации пользователю без завершения работы dapp.
164
164
  $stderr.puts(::Dapp::Dapp.paint_string(::Dapp::Helper::NetStatus.message(e), :warning))
165
- sentry_exception(e, extra: {"job-spec" => job.spec})
166
165
  end
167
166
 
168
167
  end # Thread
@@ -13,8 +13,8 @@ module Dapp
13
13
  template_relative_path_pattern = Pathname(File.expand_path(template_path_pattern)).subpath_of(path('.helm'))
14
14
  template_relative_path_pattern ||= template_path_pattern
15
15
 
16
- File.fnmatch?(template_relative_path_pattern, template_path_without_chart_name, File::FNM_PATHNAME|File::FNM_DOTMATCH) ||
17
- File.fnmatch?(template_relative_path_pattern, template_path, File::FNM_PATHNAME|File::FNM_DOTMATCH)
16
+ File.fnmatch?(template_relative_path_pattern, template_path_without_chart_name, File::FNM_PATHNAME) ||
17
+ File.fnmatch?(template_relative_path_pattern, template_path, File::FNM_PATHNAME)
18
18
  end
19
19
  end
20
20
  else
data/lib/dapp/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Dapp
2
- VERSION = "0.25.8"
3
- BUILD_CACHE_VERSION = 26.2
2
+ VERSION = "0.26.1"
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.25.8
4
+ version: 0.26.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: 2018-03-16 00:00:00.000000000 Z
11
+ date: 2018-02-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mixlib-shellout
@@ -187,33 +187,19 @@ dependencies:
187
187
  - !ruby/object:Gem::Version
188
188
  version: 1.0.6
189
189
  - !ruby/object:Gem::Dependency
190
- name: sentry-raven
190
+ name: progressbar
191
191
  requirement: !ruby/object:Gem::Requirement
192
192
  requirements:
193
193
  - - "~>"
194
194
  - !ruby/object:Gem::Version
195
- version: 2.7.2
195
+ version: 1.9.0
196
196
  type: :runtime
197
197
  prerelease: false
198
198
  version_requirements: !ruby/object:Gem::Requirement
199
199
  requirements:
200
200
  - - "~>"
201
201
  - !ruby/object:Gem::Version
202
- version: 2.7.2
203
- - !ruby/object:Gem::Dependency
204
- name: toml-rb
205
- requirement: !ruby/object:Gem::Requirement
206
- requirements:
207
- - - "~>"
208
- - !ruby/object:Gem::Version
209
- version: 1.1.1
210
- type: :runtime
211
- prerelease: false
212
- version_requirements: !ruby/object:Gem::Requirement
213
- requirements:
214
- - - "~>"
215
- - !ruby/object:Gem::Version
216
- version: 1.1.1
202
+ version: 1.9.0
217
203
  - !ruby/object:Gem::Dependency
218
204
  name: bundler
219
205
  requirement: !ruby/object:Gem::Requirement
@@ -476,7 +462,6 @@ files:
476
462
  - lib/dapp/dapp/logging/paint.rb
477
463
  - lib/dapp/dapp/logging/process.rb
478
464
  - lib/dapp/dapp/option_tags.rb
479
- - lib/dapp/dapp/sentry.rb
480
465
  - lib/dapp/dapp/shellout/base.rb
481
466
  - lib/dapp/dapp/shellout/streaming.rb
482
467
  - lib/dapp/dapp/slug.rb
@@ -664,6 +649,7 @@ files:
664
649
  - lib/dapp/dimg/image/stage.rb
665
650
  - lib/dapp/dimg/lock/base.rb
666
651
  - lib/dapp/dimg/lock/file.rb
652
+ - lib/dapp/downloader.rb
667
653
  - lib/dapp/error/base.rb
668
654
  - lib/dapp/error/command.rb
669
655
  - lib/dapp/error/config.rb
@@ -678,7 +664,6 @@ files:
678
664
  - lib/dapp/helper/sha256.rb
679
665
  - lib/dapp/helper/tar.rb
680
666
  - lib/dapp/helper/trivia.rb
681
- - lib/dapp/helper/url.rb
682
667
  - lib/dapp/helper/yaml.rb
683
668
  - lib/dapp/kube.rb
684
669
  - lib/dapp/kube/cli/cli.rb
@@ -1,112 +0,0 @@
1
- module Dapp
2
- class Dapp
3
- module Sentry
4
- def sentry_message(msg, **kwargs)
5
- return if not ensure_sentry_configured
6
- kwargs[:level] ||= "info"
7
- Raven.capture_message(msg, _make_sentry_params(**kwargs))
8
- end
9
-
10
- def sentry_exception(exception, **kwargs)
11
- return if not ensure_sentry_configured
12
- (kwargs[:tags] ||= {})['error-code'] = begin
13
- net_status = exception.net_status
14
- [net_status[:context], net_status[:code]].compact.join('_')
15
- end
16
- Raven.capture_exception(exception, _make_sentry_params(**kwargs))
17
- end
18
-
19
- def ensure_sentry_configured
20
- return false unless sentry_settings = settings["sentry"]
21
-
22
- unless @sentry_settings_configured
23
- Raven.configure do |config|
24
- logger = ::Logger.new(STDOUT)
25
- logger.level = ::Logger::WARN
26
-
27
- config.logger = logger
28
- config.dsn = sentry_settings["dsn"]
29
- end
30
-
31
- @sentry_settings_configured = true
32
- end
33
-
34
- return true
35
- end
36
-
37
- def _make_sentry_params(level: nil, tags: {}, extra: {}, user: {})
38
- {
39
- level: level,
40
- tags: _sentry_tags_context.merge(tags),
41
- extra: _sentry_extra_context.merge(extra),
42
- user: _sentry_user_context.merge(user),
43
- }
44
- end
45
-
46
- def _sentry_extra_context
47
- @_sentry_extra_context ||= {
48
- "pwd" => Dir.pwd,
49
- "dapp-dir" => self.work_dir,
50
- "options" => self.options,
51
- "env-options" => {
52
- "DAPP_FORCE_SAVE_CACHE" => ENV["DAPP_FORCE_SAVE_CACHE"],
53
- "DAPP_BIN_DAPPFILE_YML" => ENV["DAPP_BIN_DAPPFILE_YML"],
54
- "ANSIBLE_ARGS" => ENV["ANSIBLE_ARGS"],
55
- "DAPP_CHEF_DEBUG" => ENV["DAPP_CHEF_DEBUG"],
56
- },
57
- }.tap {|extra|
58
- extra["ci-env"] = {"CI" => ENV["CI"]}
59
- ENV.select {|k, v| k.start_with?("CI_")}.each do |k, v|
60
- extra["ci-env"][k] = v
61
- end
62
- }
63
- end
64
-
65
- def _sentry_tags_context
66
- name = options[:name] ||
67
- @_sentry_tags_context ||= {
68
- "dapp-short-version" => ::Dapp::VERSION.split(".")[0..1].join("."),
69
- "dapp-version" => ::Dapp::VERSION,
70
- "dapp-build-cache-version" => ::Dapp::BUILD_CACHE_VERSION,
71
- "dapp-command" => self.options[:dapp_command],
72
- }.tap {|tags|
73
- git_config_path = File.join(Dir.pwd, ".git/config")
74
-
75
- tags["dapp-name"] = options[:name]
76
-
77
- if File.exists? git_config_path
78
- cfg = IniFile.load(File.join(Dir.pwd, ".git/config"))
79
- remote_origin_cfg = cfg['remote "origin"']
80
- remote_origin_url = remote_origin_cfg["url"]
81
- if remote_origin_url
82
- tags["dapp-name"] ||= begin
83
- repo_name = remote_origin_url.split('/').last
84
- repo_name = repo_name[/.*(?=\.git)/] if repo_name.end_with? '.git'
85
- repo_name
86
- end
87
-
88
- tags["git-host"] = self.get_host_from_git_url(remote_origin_url)
89
-
90
- git_name = self.git_url_to_name(remote_origin_url)
91
-
92
- tags["git-group"] = git_name.partition("/")[0]
93
- tags["git-name"] = git_name
94
- end
95
- end
96
-
97
- tags["dapp-name"] ||= File.basename(Dir.pwd)
98
-
99
- begin
100
- ver = self.class.host_docker_minor_version
101
- tags["docker-minor-version"] = ver.to_s
102
- rescue ::Exception
103
- end
104
- }
105
- end
106
-
107
- def _sentry_user_context
108
- @_sentry_user_context ||= {}
109
- end
110
- end # Sentry
111
- end # Dapp
112
- end # Dapp
@@ -1,23 +0,0 @@
1
- module Dapp
2
- module Helper
3
- module Url
4
- def git_url_to_name(url)
5
- url_without_scheme = url.split("://", 2).last
6
- # This may be broken, because "@" should delimit creds, not a ":"
7
- url_without_creds = url_without_scheme.split(":", 2).last
8
- url_without_creds.gsub(%r{.*?([^\/ ]+\/[^\/ ]+)\.git}, '\\1')
9
- end
10
-
11
- def get_host_from_git_url(url)
12
- url_without_scheme = url.split("://", 2).last
13
- url_without_creds = url_without_scheme.split("@", 2).last
14
-
15
- # Split out part after ":" in this kind of url: github.com:flant/dapp.git
16
- url_part = url_without_creds.split(":", 2).first
17
-
18
- # Split out part after first "/": github.com/flant/dapp.git
19
- url_part.split("/", 2).first
20
- end
21
- end # Url
22
- end # Helper
23
- end # Dapp