dapp 0.32.10 → 0.33.0

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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/bin/dapp +1 -23
  3. data/config/en/net_status.yml +7 -0
  4. data/lib/dapp.rb +3 -3
  5. data/lib/dapp/dapp.rb +13 -0
  6. data/lib/dapp/dapp/dappfile.rb +2 -2
  7. data/lib/dapp/dapp/deps/base.rb +5 -37
  8. data/lib/dapp/dapp/deps/common.rb +25 -0
  9. data/lib/dapp/dapp/deps/gitartifact.rb +2 -25
  10. data/lib/dapp/dapp/deps/toolchain.rb +1 -23
  11. data/lib/dapp/dapp/logging/base.rb +3 -3
  12. data/lib/dapp/dapp/ruby2go.rb +96 -0
  13. data/lib/dapp/dapp/sentry.rb +0 -1
  14. data/lib/dapp/dapp/shellout/base.rb +4 -2
  15. data/lib/dapp/dimg/build/stage/artifact_base.rb +7 -6
  16. data/lib/dapp/dimg/build/stage/base.rb +37 -7
  17. data/lib/dapp/dimg/build/stage/from.rb +1 -1
  18. data/lib/dapp/dimg/builder/ansible.rb +1 -209
  19. data/lib/dapp/dimg/builder/base.rb +0 -5
  20. data/lib/dapp/dimg/builder/none.rb +1 -34
  21. data/lib/dapp/dimg/builder/ruby2go.rb +51 -0
  22. data/lib/dapp/dimg/builder/shell.rb +1 -25
  23. data/lib/dapp/dimg/cli/command/dimg/bp.rb +10 -15
  24. data/lib/dapp/dimg/cli/command/dimg/build.rb +0 -5
  25. data/lib/dapp/dimg/config/directive/docker/base.rb +1 -1
  26. data/lib/dapp/dimg/dapp/command/build_context/export.rb +1 -1
  27. data/lib/dapp/dimg/dapp/command/build_context/import.rb +1 -1
  28. data/lib/dapp/dimg/dapp/command/cleanup_repo.rb +59 -90
  29. data/lib/dapp/dimg/dapp/command/common.rb +60 -74
  30. data/lib/dapp/dimg/dapp/command/mrproper.rb +2 -17
  31. data/lib/dapp/dimg/dapp/command/stages/cleanup_local.rb +9 -6
  32. data/lib/dapp/dimg/dimg.rb +26 -43
  33. data/lib/dapp/dimg/docker_registry/base/authorization.rb +1 -16
  34. data/lib/dapp/dimg/git_artifact.rb +142 -21
  35. data/lib/dapp/dimg/git_repo/base.rb +11 -0
  36. data/lib/dapp/dimg/git_repo/local.rb +14 -0
  37. data/lib/dapp/dimg/git_repo/remote.rb +25 -34
  38. data/lib/dapp/dimg/image/argument.rb +12 -58
  39. data/lib/dapp/dimg/image/stage.rb +202 -43
  40. data/lib/dapp/kube/kubernetes/client.rb +0 -6
  41. data/lib/dapp/kube/kubernetes/manager/deployment.rb +18 -30
  42. data/lib/dapp/version.rb +1 -1
  43. metadata +8 -8
  44. data/lib/dapp/dimg/builder/ansible/assets.rb +0 -349
  45. data/lib/dapp/dimg/exception/introspect_image.rb +0 -7
  46. data/lib/dapp/dimg/image/docker.rb +0 -144
@@ -13,6 +13,17 @@ module Dapp
13
13
  @name = name
14
14
  end
15
15
 
16
+ def get_ruby2go_state_hash
17
+ {
18
+ "Dapp" => dapp.get_ruby2go_state_hash,
19
+ "Name" => @name.to_s,
20
+ }
21
+ end
22
+
23
+ def set_ruby2go_state_hash(state)
24
+ @name = state["Name"]
25
+ end
26
+
16
27
  def exclude_paths
17
28
  []
18
29
  end
@@ -9,6 +9,20 @@ module Dapp
9
9
  self.path = path
10
10
  end
11
11
 
12
+ def get_ruby2go_state_hash
13
+ super.tap {|res|
14
+ p = @path.to_s
15
+ p = File.dirname(@path) if File.basename(@path) == ".git"
16
+ res["Path"] = p
17
+ res["OrigPath"] = @path.to_s
18
+ }
19
+ end
20
+
21
+ def set_ruby2go_state_hash(state)
22
+ super(state)
23
+ @path = state["OrigPath"]
24
+ end
25
+
12
26
  def path=(path)
13
27
  @path ||= Pathname(Rugged::Repository.new(path).path)
14
28
  rescue Rugged::RepositoryError, Rugged::OSError => _e
@@ -8,7 +8,7 @@ module Dapp
8
8
 
9
9
  class << self
10
10
  def get_or_create(dapp, name, url:)
11
- repositories[url] ||= new(dapp, name, url: url).tap(&:fetch!)
11
+ repositories[url] ||= new(dapp, name, url: url).tap(&:clone_and_fetch)
12
12
  end
13
13
 
14
14
  def repositories
@@ -20,20 +20,29 @@ module Dapp
20
20
  super(dapp, name)
21
21
 
22
22
  @url = url
23
+ end
23
24
 
24
- _with_lock do
25
- dapp.log_secondary_process(dapp.t(code: 'process.git_artifact_clone', data: { url: url }), short: true) do
26
- begin
27
- if [:https, :ssh].include?(remote_origin_url_protocol) && !Rugged.features.include?(remote_origin_url_protocol)
28
- raise Error::Rugged, code: :rugged_protocol_not_supported, data: { url: url, protocol: remote_origin_url_protocol }
29
- end
30
-
31
- Rugged::Repository.clone_at(url, path.to_s, bare: true, credentials: _rugged_credentials)
32
- rescue Rugged::NetworkError, Rugged::SslError, Rugged::OSError, Rugged::SshError => e
33
- raise Error::Rugged, code: :rugged_remote_error, data: { message: e.message, url: url }
34
- end
35
- end
36
- end unless path.directory?
25
+ def ruby2go_method(method, args_hash={})
26
+ res = dapp.ruby2go_git_repo(args_hash.merge("RemoteGitRepo" => JSON.dump(get_ruby2go_state_hash), "method" => method))
27
+
28
+ raise res["error"] if res["error"]
29
+
30
+ self.set_ruby2go_state_hash(JSON.load(res["data"]["RemoteGitRepo"]))
31
+
32
+ res["data"]["result"]
33
+ end
34
+
35
+ def get_ruby2go_state_hash
36
+ super.tap {|res|
37
+ res["Url"] = @url.to_s
38
+ res["ClonePath"] = dapp.build_path("remote_git_repo", CACHE_VERSION.to_s, dapp.consistent_uniq_slugify(name), remote_origin_url_protocol).to_s # FIXME
39
+ res["IsDryRun"] = dapp.dry_run?
40
+ }
41
+ end
42
+
43
+ def set_ruby2go_state_hash(state)
44
+ super(state)
45
+ @url = state["Url"]
37
46
  end
38
47
 
39
48
  def _with_lock(&blk)
@@ -54,26 +63,8 @@ module Dapp
54
63
  Pathname(dapp.build_path("remote_git_repo", CACHE_VERSION.to_s, dapp.consistent_uniq_slugify(name), remote_origin_url_protocol).to_s)
55
64
  end
56
65
 
57
- def fetch!
58
- _with_lock do
59
- cfg_path = path.join("config")
60
- cfg = IniFile.load(cfg_path)
61
- remote_origin_cfg = cfg['remote "origin"']
62
-
63
- old_url = remote_origin_cfg["url"]
64
- if old_url and old_url != url
65
- remote_origin_cfg["url"] = url
66
- cfg.write(filename: cfg_path)
67
- end
68
-
69
- dapp.log_secondary_process(dapp.t(code: 'process.git_artifact_fetch', data: { url: url }), short: true) do
70
- begin
71
- git.remotes.each { |remote| remote.fetch(credentials: _rugged_credentials) }
72
- rescue Rugged::SshError, Rugged::NetworkError => e
73
- raise Error::Rugged, code: :rugged_remote_error, data: { url: url, message: e.message.strip }
74
- end
75
- end
76
- end unless dapp.dry_run?
66
+ def clone_and_fetch
67
+ return ruby2go_method("CloneAndFetch")
77
68
  end
78
69
 
79
70
  def latest_branch_commit(branch)
@@ -11,11 +11,11 @@ module Dapp
11
11
  end
12
12
 
13
13
  def add_change_env(**options)
14
- add_change_option(:env, options)
14
+ (change_options[:env] ||= {}).merge!(options)
15
15
  end
16
16
 
17
17
  def add_change_label(**options)
18
- add_change_option(:label, options)
18
+ (change_options[:label] ||= {}).merge!(options)
19
19
  end
20
20
 
21
21
  def add_change_cmd(value)
@@ -31,19 +31,19 @@ module Dapp
31
31
  end
32
32
 
33
33
  def add_change_workdir(value)
34
- add_change_option(:workdir, value)
34
+ change_options[:workdir] = value
35
35
  end
36
36
 
37
37
  def add_change_user(value)
38
- add_change_option(:user, value)
38
+ change_options[:user] = value
39
39
  end
40
40
 
41
41
  def add_service_change_label(**options)
42
- add_service_change_option(:label, options)
42
+ (service_change_options[:label] ||= {}).merge!(options)
43
43
  end
44
44
 
45
- def add_env(var, value)
46
- add_option(:env, "#{var}=#{value}")
45
+ def add_env(**options)
46
+ (self.options[:env] ||= {}).merge!(options)
47
47
  end
48
48
 
49
49
  def add_volume(value)
@@ -65,10 +65,12 @@ module Dapp
65
65
  def prepare_instructions(options)
66
66
  options.map do |key, vals|
67
67
  case key
68
+ when :workdir, :user
69
+ [vals]
68
70
  when :cmd, :entrypoint
69
71
  vals = [''] if vals == [] && ::Dapp::Dapp.host_docker_minor_version >= Gem::Version.new('17.10')
70
72
  [vals]
71
- when :env, :label then vals.map(&method(:options_to_args)).flatten
73
+ when :env, :label then options_to_args(vals)
72
74
  else vals
73
75
  end.map { |val| %(#{key.to_s.upcase} #{val}) }
74
76
  end.flatten
@@ -77,7 +79,8 @@ module Dapp
77
79
  protected
78
80
 
79
81
  attr_reader :bash_commands, :service_bash_commands
80
- attr_reader :change_options, :service_change_options
82
+ attr_reader :change_options
83
+ attr_reader :service_change_options
81
84
  attr_reader :options
82
85
 
83
86
  def add_option(key, value)
@@ -96,58 +99,9 @@ module Dapp
96
99
  hash[key] = (hash[key].nil? ? [value] : (hash[key] << value)).flatten
97
100
  end
98
101
 
99
- def from_change_options
100
- return {} if from.nil?
101
- [:entrypoint, :cmd].each_with_object({}) do |option, options|
102
- options[option] = from.config_option(option.to_s.capitalize) || []
103
- end.tap do |options|
104
- workdir = from.config_option('WorkingDir')
105
- options[:workdir] = Array((workdir || '').empty? ? '/' : workdir)
106
- end
107
- end
108
-
109
102
  def options_to_args(options)
110
103
  options.map { |key, value| "#{key}=#{value}" }
111
104
  end
112
-
113
- def prepared_options
114
- all_options.map { |key, vals| Array(vals).map { |val| "--#{key}=#{val}" } }.flatten.join(' ')
115
- end
116
-
117
- def all_options
118
- service_options.in_depth_merge(options)
119
- end
120
-
121
- def all_bash_commands
122
- Array(bash_commands) + Array(service_bash_commands)
123
- end
124
-
125
- def service_options
126
- {
127
- workdir: '/',
128
- entrypoint: dapp.bash_bin,
129
- name: container_name,
130
- user: '0:0',
131
- :'volumes-from' => [dapp.base_container, dapp.toolchain_container]
132
- }
133
- end
134
-
135
- def prepared_change
136
- prepare_instructions(all_change_options).map { |instruction| %(-c '#{instruction}') }.join(' ')
137
- end
138
-
139
- def all_change_options
140
- from_change_options.merge(change_options.merge(service_change_options) { |_, v1, v2| [v1, v2].flatten })
141
- end
142
-
143
- def prepared_bash_command
144
- dapp.shellout_pack prepared_commands.join(' && ')
145
- end
146
-
147
- def prepared_commands
148
- return [dapp.true_bin] if all_bash_commands.empty?
149
- all_bash_commands
150
- end
151
105
  end
152
106
  end # Image
153
107
  end # Dimg
@@ -1,11 +1,59 @@
1
1
  module Dapp
2
2
  module Dimg
3
3
  module Image
4
- class Stage < Docker
4
+ class Stage
5
5
  include Argument
6
6
 
7
+ attr_reader :from
8
+ attr_reader :name
9
+ attr_reader :dapp
10
+
11
+ class << self
12
+ def image_by_name(name:, **kwargs)
13
+ images[name] ||= new(name: name, **kwargs)
14
+ end
15
+
16
+ def image_reset(name)
17
+ images.delete(name)
18
+ end
19
+
20
+ def images
21
+ @images ||= {}
22
+ end
23
+
24
+ def image_name_format
25
+ "#{DockerRegistry.repo_name_format}(:(?<tag>#{tag_format}))?"
26
+ end
27
+
28
+ def tag_format
29
+ '(?![-.])[a-zA-Z0-9_.-]{1,127}'
30
+ end
31
+
32
+ def image_name?(name)
33
+ !(/^#{image_name_format}$/ =~ name).nil?
34
+ end
35
+
36
+ def tag?(name)
37
+ !(/^#{tag_format}$/ =~ name).nil?
38
+ end
39
+
40
+ def save!(dapp, image_or_images, file_path, verbose: false, quiet: false)
41
+ ruby2go_command(dapp, command: :save, options: { images: Array(image_or_images), file_path: file_path })
42
+ end
43
+
44
+ def load!(dapp, file_path, verbose: false, quiet: false)
45
+ ruby2go_command(dapp, command: :load, options: { file_path: file_path })
46
+ end
47
+
48
+ def ruby2go_command(dapp, command:, **options)
49
+ dapp.ruby2go_image({ command: command }.merge(options)).tap do |res|
50
+ raise Error::Build, code: :ruby2go_image_command_failed_unexpected_error, data: { command: command, message: res["error"] } unless res["error"].nil?
51
+ break res['data']
52
+ end
53
+ end
54
+ end
55
+
7
56
  def initialize(name:, dapp:, built_id: nil, from: nil)
8
- @container_name = "dapp.build.#{SecureRandom.hex(4)}"
9
57
  @built_id = built_id
10
58
 
11
59
  @bash_commands = []
@@ -14,79 +62,190 @@ module Dapp
14
62
  @change_options = {}
15
63
  @service_change_options = {}
16
64
 
17
- super(name: name, dapp: dapp, from: from)
65
+ @from = from
66
+ @name = name
67
+ @dapp = dapp
68
+ end
69
+
70
+ def tagged?
71
+ not image_inspect.empty?
72
+ end
73
+
74
+ def built?
75
+ !built_id.nil?
18
76
  end
19
77
 
20
78
  def built_id
21
79
  @built_id ||= id
22
80
  end
23
81
 
82
+ def id
83
+ image_inspect["Id"]
84
+ end
85
+
86
+ def labels
87
+ built_image_inspect!.fetch('Config', {}).fetch('Labels', {})
88
+ end
89
+
90
+ def created_at
91
+ built_image_inspect!["Created"]
92
+ end
93
+
94
+ def size
95
+ Float(built_image_inspect!["Size"])
96
+ end
97
+
98
+ def built_image_inspect!
99
+ built_image_inspect
100
+ end
101
+
102
+ def built_image_inspect
103
+ @built_image_inspect || image_inspect
104
+ end
105
+
106
+ def reset_image_inspect
107
+ @image_inspect = nil
108
+ end
109
+
110
+ def image_inspect
111
+ ruby2go_command(:inspect, extended_image_option: false) if @image_inspect.nil?
112
+ @image_inspect
113
+ end
114
+
115
+ def pull!
116
+ dapp.log_secondary_process(dapp.t(code: 'process.image_pull', data: { name: name })) do
117
+ ruby2go_command(:pull)
118
+ end
119
+ end
120
+
121
+ def push!
122
+ dapp.log_secondary_process(dapp.t(code: 'process.image_push', data: { name: name })) do
123
+ ruby2go_command(:push)
124
+ end
125
+ end
126
+
24
127
  def build!
25
- run!
26
- @built_id = commit!
27
- ensure
28
- dapp.shellout("#{dapp.host_docker} rm #{container_name}")
128
+ res = self.dapp.ruby2go_image(**ruby2go_image_build_options)
129
+ if res["error"].nil?
130
+ set_ruby2go_state_hash(JSON.load(res['data']['image']))
131
+ elsif res["error"].start_with? "container run failed"
132
+ raise Error::Build, code: :ruby2go_image_command_failed, data: { command: "build" }
133
+ else
134
+ raise Error::Build, code: :ruby2go_image_command_failed_unexpected_error, data: { command: "build", message: res["error"] }
135
+ end
29
136
  end
30
137
 
31
- def built?
32
- !built_id.nil?
138
+ def ruby2go_image_build_options
139
+ {
140
+ image: ruby2go_image_option,
141
+ command: :build,
142
+ options: {
143
+ introspection: {
144
+ before: dapp.introspect_before_error?,
145
+ after: dapp.introspect_error?
146
+ }
147
+ }
148
+ }
149
+ end
150
+
151
+ def introspect!
152
+ ruby2go_command(:introspect)
33
153
  end
34
154
 
35
155
  def export!(name)
36
- tag!(name).tap do |image|
37
- image.push!
38
- image.untag!
39
- end
156
+ ruby2go_command(:export, options: { name: name })
40
157
  end
41
158
 
42
159
  def tag!(name)
43
- clone!(name).tap do |image|
44
- self.class.tag!(id: image.built_id, tag: image.name)
45
- end
160
+ ruby2go_command(:tag, options: { name: name })
46
161
  end
47
162
 
48
163
  def import!(name)
49
- clone!(name).tap do |image|
50
- image.pull!
51
- @built_id = image.built_id
52
- save_in_cache!
53
- image.untag!
54
- end
164
+ ruby2go_command(:import, options: { name: name })
55
165
  end
56
166
 
57
167
  def save_in_cache!
58
- dapp.log_warning(desc: { code: :another_image_already_tagged }) if !(existed_id = id).nil? && built_id != existed_id
59
- self.class.tag!(id: built_id, tag: name)
168
+ ruby2go_command(:save_in_cache)
60
169
  end
61
170
 
62
- def labels
63
- config_option('Labels')
171
+ def untag!
172
+ ruby2go_command(:untag)
64
173
  end
65
174
 
66
- protected
175
+ def ruby2go_command(command, extended_image_option: true, options: {})
176
+ command_options = ruby2go_command_options(command, extended_image_option: extended_image_option).in_depth_merge(options: options)
177
+ self.class.ruby2go_command(dapp, **command_options).tap do |data|
178
+ set_ruby2go_state_hash(JSON.load(data['image']))
179
+ end
180
+ end
67
181
 
68
- attr_reader :container_name
182
+ def ruby2go_command_options(command, extended_image_option: true)
183
+ image = begin
184
+ if extended_image_option
185
+ ruby2go_image_option
186
+ else
187
+ JSON.dump({name: name})
188
+ end
189
+ end
69
190
 
70
- def run!
71
- raise Error::Build, code: :built_id_not_defined if from.built_id.nil?
72
- dapp.shellout!("#{dapp.host_docker} run #{prepared_options} #{from.built_id} -ec '#{prepared_bash_command}'", verbose: true)
73
- rescue ::Dapp::Error::Shellout => error
74
- dapp.log_warning(desc: { code: :launched_command, data: { command: prepared_commands.join(' && ') }, context: :container })
191
+ {
192
+ image: image,
193
+ command: command,
194
+ }
195
+ end
75
196
 
76
- raise unless dapp.introspect_error? || dapp.introspect_before_error?
77
- built_id = dapp.introspect_error? ? commit! : from.built_id
78
- raise Exception::IntrospectImage, data: { built_id: built_id,
79
- options: prepared_options,
80
- rmi: dapp.introspect_error?,
81
- error: error }
197
+ def ruby2go_image_option
198
+ JSON.dump(get_ruby2go_state_hash)
82
199
  end
83
200
 
84
- def commit!
85
- dapp.shellout!("#{dapp.host_docker} commit #{prepared_change} #{container_name}").stdout.strip
201
+ def get_ruby2go_state_hash
202
+ [
203
+ :name,
204
+ :from,
205
+ :built_id,
206
+ :built_image_inspect,
207
+ :image_inspect,
208
+ :bash_commands,
209
+ :service_bash_commands,
210
+ :options,
211
+ :change_options,
212
+ :service_change_options,
213
+ ].map do |name|
214
+ if name == :from
215
+ [name, from.get_ruby2go_state_hash] unless from.nil?
216
+ elsif name == :built_image_inspect && built_image_inspect.empty?
217
+ elsif name == :image_inspect && image_inspect.empty?
218
+ else
219
+ [name, send(name)]
220
+ end
221
+ end
222
+ .compact
223
+ .to_h
86
224
  end
87
225
 
88
- def clone!(name)
89
- self.class.new(name: name, dapp: dapp, built_id: built_id)
226
+ def set_ruby2go_state_hash(state_hash)
227
+ state_hash.each do |name, value|
228
+ variable = "@#{name}".to_sym
229
+
230
+ case name
231
+ when "from"
232
+ from.set_ruby2go_state_hash(value) unless from.nil? || value.nil?
233
+ when "built_id"
234
+ if value.to_s.empty?
235
+ @built_id = nil
236
+ else
237
+ @built_id = value
238
+ end
239
+ when "image_inspect"
240
+ instance_variable_set(variable, (value || {}))
241
+ when "options", "change_options", "service_change_options"
242
+ instance_variable_set(variable, (value || {}).reject { |_, v| v.nil? || v.empty? }.symbolize_keys)
243
+ when "bash_commands", "service_bash_commands"
244
+ instance_variable_set(variable, value || [])
245
+ else
246
+ instance_variable_set(variable, value)
247
+ end
248
+ end
90
249
  end
91
250
  end # Stage
92
251
  end # Image