dapp 0.14.12 → 0.14.13

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: 13bccb197061f7d78e8f74f498248f6aa2c19833
4
- data.tar.gz: d5a9c8d733f8d3f9562d3af9219930220aa78c90
3
+ metadata.gz: 466d76237b9cd32cacddaa69e3b86b673f0fb2b9
4
+ data.tar.gz: f8ced9c91a8aa80d2ad9ac8b352dbcd6ac2c534a
5
5
  SHA512:
6
- metadata.gz: ca8cf1edb04f43bfac8303ff27696214ce848a013d04c2c19c3e1ffa8f81274032f1e1a533459d1dce5b31a634a191e632b99d96880b9cc9030bef27e27320f9
7
- data.tar.gz: b7a031ef19524e04b38cb274d5ddd5261275ffe94591401001eee285a9eff17ac78264ff39de5dc6cef1d1ad658ae95906ba54e265d83c8db7a44c8b7e2fdfbf
6
+ metadata.gz: 4103ba572ba370b662a8be1cf78650fa1cdf77826ad9eae30a8c2ac43efe4a5fab3ca532ace3ab33e0243b0a0ae0550f8c344e517b6f294ecd915a710dc19e6d
7
+ data.tar.gz: f48ce8e3229dc74e548a6f442d242c2564b02dcac0bbe2f7aebdc120884b4c1eb7343bbdd37b7dd3f6ef98878ed2184369baa70d44ae6ec4fece0582b56fe618
@@ -116,6 +116,7 @@ en:
116
116
  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`!"
117
117
  branch_not_exist_in_remote_git_repository: "Remote git repo `%{url}`: branch `%{branch}` not exist!"
118
118
  rugged_protocol_not_supported: "Rugged has been compiled without support for `%{protocol}`.\nGit repositories will not be reachable via `%{protocol}` (`%{url}`).\nRugged.features should include `%{protocol}`."
119
+ submodule_not_supported: "Git submodules not supported! (`%{path}`)"
119
120
  lock:
120
121
  timeout: "Could not obtain lock for `%{name}` within %{timeout} seconds"
121
122
  app:
@@ -56,6 +56,20 @@ module Dapp
56
56
  super()
57
57
  end
58
58
 
59
+ def run_dapp_command(run_method, *args)
60
+ dapp = ::Dapp::Dapp.new(*args)
61
+ begin
62
+ dapp.host_docker_login
63
+ if run_method.nil?
64
+ yield dapp if block_given?
65
+ else
66
+ dapp.public_send(run_method)
67
+ end
68
+ ensure
69
+ dapp.terminate
70
+ end
71
+ end
72
+
59
73
  def run(_argv = ARGV)
60
74
  raise
61
75
  end
@@ -13,6 +13,7 @@ module Dapp
13
13
 
14
14
  include SshAgent
15
15
  include Helper::Sha256
16
+ extend Helper::Trivia
16
17
  include Helper::Trivia
17
18
  include Helper::Tar
18
19
 
@@ -24,12 +25,16 @@ module Dapp
24
25
  attr_reader :options
25
26
 
26
27
  def initialize(options: {})
27
- @options = options
28
+ self.class.options.merge!(options)
28
29
  Logging::I18n.initialize
29
30
  validate_config_options!
30
31
  Logging::Paint.initialize(option_color)
31
32
  end
32
33
 
34
+ def options
35
+ self.class.options
36
+ end
37
+
33
38
  def name
34
39
  @name ||= begin
35
40
  if git_url
@@ -67,7 +72,7 @@ module Dapp
67
72
  end
68
73
 
69
74
  def tmp_base_dir
70
- File.expand_path(options[:tmp_dir_prefix] || '/tmp')
75
+ self.class.tmp_base_dir
71
76
  end
72
77
 
73
78
  def build_path(*path)
@@ -98,26 +103,73 @@ module Dapp
98
103
  name
99
104
  end
100
105
 
106
+ def terminate
107
+ FileUtils.rmtree(host_docker_tmp_config_dir)
108
+ end
109
+
101
110
  def host_docker
102
111
  self.class.host_docker
103
112
  end
104
113
 
105
- def self.host_docker
106
- @host_docker ||= begin
107
- raise Error::Dapp, code: :docker_not_found if (res = shellout('which docker')).exitstatus.nonzero?
108
- docker_bin = res.stdout.strip
114
+ def host_docker_tmp_config_dir
115
+ self.class.host_docker_tmp_config_dir
116
+ end
117
+
118
+ def host_docker_login
119
+ return unless option_repo
120
+
121
+ login = proc {|u, p| shellout!("#{host_docker} login #{option_repo} -u #{u} -p #{p}")}
122
+ if options.key?(:registry_username) && options.key?(:registry_password)
123
+ login.call(options[:registry_username], options[:registry_password])
124
+ elsif ENV.key?('CI_JOB_TOKEN')
125
+ login.call('gitlab-ci-token', ENV['CI_JOB_TOKEN'])
126
+ end
127
+ end
128
+
129
+ class << self
130
+ def options
131
+ @options ||= {}
132
+ end
133
+
134
+ def host_docker
135
+ @host_docker ||= begin
136
+ raise Error::Dapp, code: :docker_not_found if (res = shellout('which docker')).exitstatus.nonzero?
137
+ docker_bin = res.stdout.strip
138
+
139
+ current_docker_version = shellout!("#{docker_bin} --version").stdout.strip
140
+ required_docker_version = '1.10.0'
141
+
142
+ if Gem::Version.new(required_docker_version) >= Gem::Version.new(current_docker_version[/(\d+\.)+\d+/])
143
+ raise Error::Dapp, code: :docker_version, data: { version: required_docker_version }
144
+ end
109
145
 
110
- current_docker_version = shellout!("#{docker_bin} --version").stdout.strip
111
- required_docker_version = '1.10.0'
146
+ [].tap do |cmd|
147
+ cmd << docker_bin
148
+ cmd << "--config #{host_docker_config_dir}"
149
+ end.join(' ')
150
+ end
151
+ end
112
152
 
113
- if Gem::Version.new(required_docker_version) >= Gem::Version.new(current_docker_version[/(\d+\.)+\d+/])
114
- raise Error::Dapp, code: :docker_version, data: { version: required_docker_version }
153
+ def host_docker_config_dir
154
+ if options_with_docker_credentials?
155
+ host_docker_tmp_config_dir
156
+ elsif ENV.key?('DAPP_DOCKER_CONFIG')
157
+ ENV['DAPP_DOCKER_CONFIG']
158
+ else
159
+ File.join(Dir.home, '.docker')
115
160
  end
161
+ end
162
+
163
+ def options_with_docker_credentials?
164
+ (options.key?(:registry_username) && options.key?(:registry_password)) || ENV.key?('CI_JOB_TOKEN')
165
+ end
166
+
167
+ def host_docker_tmp_config_dir
168
+ @host_docker_tmp_config_dir ||= Dir.mktmpdir('dapp-', tmp_base_dir)
169
+ end
116
170
 
117
- [].tap do |cmd|
118
- cmd << docker_bin
119
- cmd << "--config #{ENV['DAPP_DOCKER_CONFIG']}" if ENV.key?('DAPP_DOCKER_CONFIG')
120
- end.join(' ')
171
+ def tmp_base_dir
172
+ File.expand_path(options[:tmp_dir_prefix] || '/tmp')
121
173
  end
122
174
  end
123
175
  end # Dapp
@@ -3,7 +3,7 @@ module Dapp::Dimg::CLI
3
3
  class Base < ::Dapp::CLI::Command::Base
4
4
  def run(argv = ARGV)
5
5
  self.class.parse_options(self, argv)
6
- ::Dapp::Dapp.new(options: cli_options(dimgs_patterns: cli_arguments)).public_send(run_method)
6
+ run_dapp_command(run_method, options: cli_options(dimgs_patterns: cli_arguments))
7
7
  end
8
8
 
9
9
  def run_method
@@ -50,10 +50,16 @@ BANNER
50
50
  long: '--with-stages',
51
51
  boolean: true
52
52
 
53
+ option :registry_username,
54
+ long: '--registry-username USERNAME'
55
+
56
+ option :registry_password,
57
+ long: '--registry-password PASSWORD'
58
+
53
59
  def run(argv = ARGV)
54
60
  self.class.parse_options(self, argv)
55
61
  repo = self.class.required_argument(self, 'repo')
56
- ::Dapp::Dapp.new(options: cli_options(dimgs_patterns: cli_arguments, repo: repo)).public_send(class_to_lowercase)
62
+ run_dapp_command(run_method, options: cli_options(dimgs_patterns: cli_arguments, repo: repo))
57
63
  end
58
64
  end
59
65
  end
@@ -51,7 +51,9 @@ BANNER
51
51
  index = filtered_args.index('--') || filtered_args.count
52
52
  docker_options = index.nonzero? ? filtered_args.slice(0..index - 1) : []
53
53
  command = filtered_args.slice(index + 1..-1) || []
54
- ::Dapp::Dapp.new(options: cli_options(dimgs_patterns: patterns)).run(docker_options, command)
54
+ run_dapp_command(nil, options: cli_options(dimgs_patterns: patterns)) do |dapp|
55
+ dapp.run(docker_options, command)
56
+ end
55
57
  end
56
58
  end
57
59
  end
@@ -24,10 +24,16 @@ BANNER
24
24
  long: '--improper-repo-cache',
25
25
  boolean: true
26
26
 
27
+ option :registry_username,
28
+ long: '--registry-username USERNAME'
29
+
30
+ option :registry_password,
31
+ long: '--registry-password PASSWORD'
32
+
27
33
  def run(argv = ARGV)
28
34
  self.class.parse_options(self, argv)
29
35
  repository = repo
30
- ::Dapp::Dapp.new(options: cli_options(dimgs_patterns: cli_arguments, repo: repository)).send(run_method)
36
+ run_dapp_command(run_method, options: cli_options(dimgs_patterns: cli_arguments, repo: repository))
31
37
  end
32
38
 
33
39
  def repo
@@ -14,7 +14,7 @@ Options:
14
14
  BANNER
15
15
  def run(argv = ARGV)
16
16
  self.class.parse_options(self, argv)
17
- ::Dapp::Dapp.new(options: cli_options(dimgs_patterns: cli_arguments)).stages_flush_local
17
+ run_dapp_command(:stages_flush_local, options: cli_options(dimgs_patterns: cli_arguments))
18
18
  end
19
19
  end
20
20
  end
@@ -12,10 +12,16 @@ Usage:
12
12
 
13
13
  Options:
14
14
  BANNER
15
+ option :registry_username,
16
+ long: '--registry-username USERNAME'
17
+
18
+ option :registry_password,
19
+ long: '--registry-password PASSWORD'
20
+
15
21
  def run(argv = ARGV)
16
22
  self.class.parse_options(self, argv)
17
23
  repo = self.class.required_argument(self, 'repo')
18
- ::Dapp::Dapp.new(options: cli_options(dimgs_patterns: cli_arguments, repo: repo)).stages_flush_repo
24
+ run_dapp_command(:stages_flush_repo, options: cli_options(dimgs_patterns: cli_arguments, repo: repo))
19
25
  end
20
26
  end
21
27
  end
@@ -16,10 +16,16 @@ BANNER
16
16
  long: '--all',
17
17
  boolean: true
18
18
 
19
+ option :registry_username,
20
+ long: '--registry-username USERNAME'
21
+
22
+ option :registry_password,
23
+ long: '--registry-password PASSWORD'
24
+
19
25
  def run(argv = ARGV)
20
26
  self.class.parse_options(self, argv)
21
27
  repo = self.class.required_argument(self, 'repo')
22
- ::Dapp::Dapp.new(options: cli_options(dimgs_patterns: cli_arguments, repo: repo)).stages_pull
28
+ run_dapp_command(:stages_pull, options: cli_options(dimgs_patterns: cli_arguments, repo: repo))
23
29
  end
24
30
  end
25
31
  end
@@ -12,10 +12,16 @@ Usage:
12
12
 
13
13
  Options:
14
14
  BANNER
15
+ option :registry_username,
16
+ long: '--registry-username USERNAME'
17
+
18
+ option :registry_password,
19
+ long: '--registry-password PASSWORD'
20
+
15
21
  def run(argv = ARGV)
16
22
  self.class.parse_options(self, argv)
17
23
  repo = self.class.required_argument(self, 'repo')
18
- ::Dapp::Dapp.new(options: cli_options(dimgs_patterns: cli_arguments, repo: repo)).stages_push
24
+ run_dapp_command(:stages_push, options: cli_options(dimgs_patterns: cli_arguments, repo: repo))
19
25
  end
20
26
  end
21
27
  end
@@ -16,7 +16,9 @@ BANNER
16
16
  def run(argv = ARGV)
17
17
  self.class.parse_options(self, argv)
18
18
  tag = self.class.required_argument(self, 'tag')
19
- ::Dapp::Dapp.new(options: cli_options(dimgs_patterns: cli_arguments)).public_send(class_to_lowercase, tag)
19
+ run_dapp_command(nil, options: cli_options(dimgs_patterns: cli_arguments)) do
20
+ dapp.public_send(run_method, tag)
21
+ end
20
22
  end
21
23
  end
22
24
  end
@@ -35,10 +35,14 @@ module Dapp
35
35
  lock("#{name}.images") do
36
36
  log_step_with_indent(name) do
37
37
  dapp_dangling_images_flush
38
- dimgs, stages = dapp_images_hash.partition { |_, image_id| repo_dimgs.values.include?(image_id) }
39
- dimgs = dimgs.to_h
40
- stages = stages.to_h
41
- dimgs.each { |_, aiid| except_image_with_parents(aiid, stages) }
38
+ dimgs, stages = dapp_images_hash.partition { |_, image_spec| repo_dimgs.values.include?(image_spec[:id]) }.map(&:to_h)
39
+ dimgs.each { |_, dimg_spec| except_image_with_parents(dimg_spec[:id], stages) }
40
+
41
+ # Удаление только образов старше
42
+ stages.delete_if do |_, stage_spec|
43
+ Time.now - stage_spec[:created_at] < 2*60*60
44
+ end
45
+
42
46
  remove_images(stages.keys)
43
47
  end
44
48
  end
@@ -60,9 +64,11 @@ module Dapp
60
64
  end
61
65
 
62
66
  def dapp_images_hash
63
- shellout!(%(#{host_docker} images --format "{{.Repository}}:{{.Tag}};{{.ID}}" --no-trunc #{stage_cache})).stdout.lines.map do |line|
64
- line.strip.split(';')
65
- end.to_h
67
+ shellout!(%(#{host_docker} images --format "{{.Repository}}:{{.Tag}};{{.ID}};{{.CreatedAt}}" --no-trunc #{stage_cache}))
68
+ .stdout.lines.map do |line|
69
+ name, id, created_at = line.strip.split(';', 3)
70
+ [name, {name: name, id: id, created_at: Time.parse(created_at)}]
71
+ end.to_h
66
72
  end
67
73
 
68
74
  def except_image_with_parents(image_id, stages)
@@ -70,11 +76,11 @@ module Dapp
70
76
  image_dapp_artifacts_label(image_id).each { |aiid| except_image_with_parents(aiid, stages) }
71
77
  iid = image_id
72
78
  loop do
73
- stages.delete_if { |_, siid| siid == iid }
79
+ stages.delete_if { |_, stage_spec| stage_spec[:id] == iid }
74
80
  break if (iid = image_parent(iid)).empty?
75
81
  end
76
82
  else
77
- stages.delete_if { |_, siid| siid == image_id }
83
+ stages.delete_if { |_, stage_spec| stage_spec[:id] == image_id }
78
84
  end
79
85
  end
80
86
 
@@ -46,7 +46,7 @@ module Dapp
46
46
  end
47
47
 
48
48
  def auths_section_from_docker_config
49
- file = Pathname(File.join(Dir.home, '.docker', 'config.json'))
49
+ file = Pathname(::Dapp::Dapp.host_docker_config_dir, 'config.json')
50
50
  user_not_authorized! unless file.exist?
51
51
  JSON.load(file.read)['auths'].tap { |auths| user_not_authorized! if auths.nil? }
52
52
  end
@@ -258,7 +258,7 @@ module Dapp
258
258
  def archive_diff_pathes(stage, from_commit, to_commit)
259
259
  diff_patches(from_commit, to_commit).each do |patch|
260
260
  entry = patch.delta.new_file
261
-
261
+ raise_if_submodule_patch!(patch)
262
262
  content = begin
263
263
  if to_commit == nil
264
264
  next unless (path = repo.path.dirname.join(entry[:path])).file?
@@ -295,11 +295,21 @@ module Dapp
295
295
 
296
296
  def patch_file(stage, from_commit, to_commit)
297
297
  File.open(repo.dimg.tmp_path('patches', patch_file_name(from_commit, to_commit)), File::RDWR | File::CREAT) do |f|
298
- diff_patches(from_commit, to_commit).each { |patch| f.write change_patch_new_file_path(stage, patch) }
298
+ diff_patches(from_commit, to_commit).each do |patch|
299
+ raise_if_submodule_patch!(patch)
300
+ f.write change_patch_new_file_path(stage, patch)
301
+ end
299
302
  end
300
303
  repo.dimg.container_tmp_path('patches', patch_file_name(from_commit, to_commit))
301
304
  end
302
305
 
306
+ def raise_if_submodule_patch!(patch) # FIXME
307
+ entry = patch.delta.new_file
308
+ if entry[:mode] == 57344 # submodule
309
+ raise Error::Rugged, code: :submodule_not_supported, data: { path: repo.path.dirname.join(entry[:path]) }
310
+ end
311
+ end
312
+
303
313
  # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
304
314
  def change_patch_new_file_path(stage, patch)
305
315
  patch.to_s.lines.tap do |lines|
@@ -3,7 +3,7 @@ module Dapp::Kube::CLI
3
3
  class Base < ::Dapp::CLI::Command::Base
4
4
  def run(argv = ARGV)
5
5
  self.class.parse_options(self, argv)
6
- ::Dapp::Dapp.new(options: cli_options).public_send(run_method)
6
+ run_dapp_command(run_method, options: cli_options)
7
7
  end
8
8
 
9
9
  def run_method
@@ -41,10 +41,16 @@ BANNER
41
41
  description: 'Default timeout to wait for resources to become ready, 300 seconds by default.',
42
42
  proc: proc {|v| Integer(v)}
43
43
 
44
+ option :registry_username,
45
+ long: '--registry-username USERNAME'
46
+
47
+ option :registry_password,
48
+ long: '--registry-password PASSWORD'
49
+
44
50
  def run(argv = ARGV)
45
51
  self.class.parse_options(self, argv)
46
52
  repo = self.class.required_argument(self, 'repo')
47
- ::Dapp::Dapp.new(options: cli_options(repo: repo)).public_send(run_method)
53
+ run_dapp_command(run_method, options: cli_options(repo: repo))
48
54
  end
49
55
  end
50
56
  end
@@ -17,7 +17,9 @@ BANNER
17
17
  def run(argv = ARGV)
18
18
  self.class.parse_options(self, argv)
19
19
  file_path = self.class.required_argument(self, 'FILE_PATH')
20
- ::Dapp::Dapp.new(options: cli_options).public_send(run_method, file_path)
20
+ run_dapp_command(nil, options: cli_options) do |dapp|
21
+ dapp.public_send(run_method, file_path)
22
+ end
21
23
  end
22
24
  end
23
25
  end
@@ -26,7 +26,9 @@ BANNER
26
26
  self.class.required_argument(self, 'FILE_PATH')
27
27
  end
28
28
  end
29
- ::Dapp::Dapp.new(options: cli_options).public_send(run_method, file_path)
29
+ run_dapp_command(nil, options: cli_options) do |dapp|
30
+ dapp.public_send(run_method, file_path)
31
+ end
30
32
  end
31
33
  end
32
34
  end
@@ -21,7 +21,9 @@ BANNER
21
21
  def run(argv = ARGV)
22
22
  self.class.parse_options(self, argv)
23
23
  file_path = cli_arguments.empty? ? nil : cli_arguments.first
24
- ::Dapp::Dapp.new(options: cli_options).public_send(run_method, file_path)
24
+ run_dapp_command(nil, options: cli_options) do |dapp|
25
+ dapp.public_send(run_method, file_path)
26
+ end
25
27
  end
26
28
  end
27
29
  end
@@ -16,7 +16,9 @@ BANNER
16
16
 
17
17
  def run(argv = ARGV)
18
18
  self.class.parse_options(self, argv)
19
- ::Dapp::Dapp.new(options: cli_options).public_send(run_method, *cli_arguments)
19
+ run_dapp_command(nil, options: cli_options) do |dapp|
20
+ dapp.public_send(run_method, *cli_arguments)
21
+ end
20
22
  end
21
23
  end
22
24
  end
@@ -1,4 +1,4 @@
1
1
  module Dapp
2
- VERSION = '0.14.12'.freeze
2
+ VERSION = '0.14.13'.freeze
3
3
  BUILD_CACHE_VERSION = 16
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.14.12
4
+ version: 0.14.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitry Stolyarov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-09-14 00:00:00.000000000 Z
11
+ date: 2017-09-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mixlib-shellout