dapp 0.32.10 → 0.33.0

Sign up to get free protection for your applications and to get access to all the features.
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