docker_core 0.0.15 → 0.0.19

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 (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/docker_core.rb +294 -195
  3. metadata +16 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e58b595913f6f5ba87bf4aade3c20a473c515b564df1f81a232e9ad869e54f1b
4
- data.tar.gz: c5cc50ba7436949f4c8b699cb304d6fddddf467326739142015d54ccc77f1933
3
+ metadata.gz: 99124c5250cb55f257fbe4c99701f860b4cc8f29c5889672b482c6a0d9ecfb4a
4
+ data.tar.gz: 539db15180fb5f835c03f199e4944b20479e71d47bc92c3d1ba7fecdbe723fb9
5
5
  SHA512:
6
- metadata.gz: 9ed2acdd8d6d18c99106dcec536a879766ab54a36c93d21b6d0e2c3661cfc33eeb28be6ccb17717e36aa98119b38211e27b11d2bd2bd84ca49c0beb3f8c43977
7
- data.tar.gz: cbdd8061e1872c87c8ef72de0fbccfd0d33fa5f1283b4832157563a3702fc9b085b2789cede7d7d6bd1eedff945a82cc0ceb8fe0af4447562aec52ace5d6d435
6
+ metadata.gz: cf8f61dc593866c8b000b9e1f6926c11594ec9b8c9bc2da52947d4410422bd25f5489ac38be02e57d765ffa1363391444e71ee250b4eb3c1e793d2bb326d1757
7
+ data.tar.gz: 29fbd93e2e05ca7cef4be7529c1d2c082081908cf8ca061c4f7c26ff759324ad56a57673443d7f86db80d5009882879aa48762c5380abeee883c7553c47104f7
data/lib/docker_core.rb CHANGED
@@ -1,264 +1,363 @@
1
+ require('etc')
1
2
  require('fileutils')
2
3
  require('json')
3
4
  require('net/http')
4
5
  require('rubygems/package')
6
+ require('thor')
5
7
  require('zlib')
6
8
 
7
9
  module DockerCore
8
- COLOR_CODE = { error: 31, info: 32, warn: 33 }
9
- ARCH_SUFFIX = { x86: '386', x86_64: 'amd64', armhf: 'armv6', aarch64: 'arm64' }
10
-
11
- # @param [String] text
12
- # @param [Integer] code
13
- def self.color(text, code)
14
- escape = "\033"
15
- prefix = "#{escape}[#{code}m"
16
- suffix = "#{escape}[0m"
17
- return "#{prefix}#{text}#{suffix}"
10
+ class Color < Thor::Shell::Color
18
11
  end
19
12
 
20
- # @param [String] text
21
- # @param [Integer] code
22
- def self.echo(text, code: self::COLOR_CODE[:info])
23
- puts(self.color(text, code))
13
+ module Image
24
14
  end
25
15
 
26
- # @param [String] title
27
- # @param [Method] run
28
- # @param [Array] argumets
29
- def self.execute(title, run, *argumets)
30
- code = self::COLOR_CODE[:warn]
31
- self.echo("> #{title}", code: code)
32
- run.call(*argumets)
33
- self.echo("< #{title}", code: code)
16
+ module Command
34
17
  end
35
18
 
36
- # @param [String] command
37
- # @param [Boolean] force
38
- def self.run(command, force: false)
39
- begin
40
- self.echo("+ #{command}")
41
- print(`#{command}`)
42
- rescue
43
- raise unless force
19
+ module Paser
20
+ # @param [String] value
21
+ def self.boolean(value)
22
+ return %w[true yes on].include?("#{value}".strip.downcase)
44
23
  end
45
- end
46
24
 
47
- # @param [String] command
48
- # @param [Boolean] force
49
- def self.suexec(command, force: false)
50
- command = "su-exec core #{command}"
51
- self.run(command, force: force)
52
- end
25
+ # @param [String] text
26
+ def self.kebab(text)
27
+ return "#{text}".gsub(/_/, '-')
28
+ end
53
29
 
54
- # @param [Integer] uid
55
- # @param [Integer] gid
56
- def self.update_user(uid: 500, gid: 500)
57
- uid = ENV.fetch('DOCKER_CORE_UID', uid)
58
- gid = ENV.fetch('DOCKER_CORE_GID', gid)
59
- self.run('deluser core', force: true)
60
- self.run('delgroup core', force: true)
61
- self.run("addgroup --system --gid=#{gid} core")
62
- self.run("adduser --system --disabled-password --no-create-home --ingroup=core --gecos=core --shell=/bin/bash --uid=#{uid} core")
63
- end
30
+ # @param [Hash] hash
31
+ def self.options(hash = {})
32
+ items = []
64
33
 
65
- # @param [Array<String>] arguments
66
- def self.path(*arguments)
67
- return Dir.glob(arguments.flatten, File::FNM_DOTMATCH).map { |item| File.path(item) }.uniq
68
- end
34
+ hash.each do |key, value|
35
+ name = '--' + self.kebab(key)
36
+
37
+ if true == value
38
+ items << name
39
+ next
40
+ end
41
+
42
+ value = "#{value}".gsub(/\\/, '\&\&').gsub('"', '\"')
43
+ items << %(#{name}="#{value}")
44
+ next
45
+ end
69
46
 
70
- # @param [Array<String>] arguments
71
- def self.chown(*arguments)
72
- self.path(*arguments).each do |path|
73
- FileUtils.chown_R('core', 'core', path, force: true)
47
+ return items
74
48
  end
75
- end
76
49
 
77
- # @param [Array<String>] arguments
78
- def self.chmod(mode, *arguments)
79
- self.path(*arguments).each do |path|
80
- FileUtils.chmod_R(mode, path, force: true)
50
+ def self.make(*arguments)
51
+ items = []
52
+
53
+ arguments.each do |item|
54
+ if item.is_a?(Array)
55
+ items.concat(item.map { |value| "#{value}" })
56
+ next
57
+ end
58
+
59
+ if item.is_a?(Hash)
60
+ items.concat(self.options(item))
61
+ next
62
+ end
63
+
64
+ items << "#{item}"
65
+ next
66
+ end
67
+
68
+ return items
81
69
  end
82
70
  end
83
71
 
84
- # @param [Array<String>] arguments
85
- def self.mkdir(*arguments, mode: nil)
86
- stack = []
87
- paths = arguments.map { |path| File.path(path) }.uniq
72
+ module Shell
73
+ USER = 'core'
74
+ GROUP = 'core'
88
75
 
89
- paths.each do |path|
90
- until path == stack.last
91
- stack << path
92
- path = File.dirname(path)
76
+ # @param [String] text
77
+ # @param [Array<String>] colors
78
+ def self.echo(text, *colors)
79
+ if 0 == colors.size
80
+ return puts(text)
93
81
  end
82
+
83
+ color = colors.map do |color|
84
+ if color.is_a?(Symbol)
85
+ next Color.const_get(color.to_s.upcase)
86
+ end
87
+
88
+ next "#{color}"
89
+ end.join
90
+
91
+ return puts("#{color}#{text}#{Color::CLEAR}")
94
92
  end
95
93
 
96
- stack.uniq.each do |path|
97
- if File.exist?(path) && false == File.directory?(path)
98
- File.delete(path)
94
+ def self.command(*arguments, substitute: false)
95
+ if substitute
96
+ arguments.unshift('su-exec', USER)
99
97
  end
98
+
99
+ return Paser.make(*arguments).join(' ')
100
100
  end
101
101
 
102
- FileUtils.mkdir_p(paths, mode: mode)
103
- end
102
+ # @param [Boolean] strip
103
+ def self.capture(*arguments, strip: true, verbose: false, substitute: false)
104
+ command = self.command(*arguments, substitute: substitute)
105
+
106
+ if verbose
107
+ self.echo("+ #{command}", Color::GREEN)
108
+ end
104
109
 
105
- # @param [Array<String>] arguments
106
- def self.rm(*arguments)
107
- self.path(*arguments).each do |path|
108
- FileUtils.rm_rf(path)
110
+ data = `#{command}`
111
+ return strip ? "#{data}".strip : data
109
112
  end
110
- end
111
113
 
112
- # @param [String, Array<String>] source
113
- # @param [String] target
114
- def self.mv(source, target)
115
- source = [source].flatten
116
- FileUtils.mv(self.path(*source), target)
117
- end
114
+ # @param [Boolean] force
115
+ def self.run(*arguments, force: false, substitute: false)
116
+ begin
117
+ data = self.capture(*arguments, strip: false, verbose: true, substitute: substitute)
118
+ print(data)
119
+ rescue
120
+ raise unless force
121
+ end
122
+ end
118
123
 
119
- # @param [String] value
120
- def self.to_boolean(value)
121
- return %w[true yes on].include?("#{value}".strip.downcase)
122
- end
124
+ # @param [Boolean] force
125
+ # @param [String] user
126
+ def self.execute(*arguments, substitute: false)
127
+ command = self.command(*arguments, substitute: substitute)
128
+ self.echo("= #{command}", Color::CYAN)
129
+ exec(command)
130
+ end
123
131
 
124
- # @param [String] stdout
125
- # @param [String] stderr
126
- def self.link_log(stdout: '', stderr: '')
127
- if '' != stdout
128
- File.symlink('/dev/stdout', File.path(stdout))
132
+ # @param [String] title
133
+ # @param [Method] delegate
134
+ # @param [Array] arguments
135
+ def self.invoke(title, delegate, *arguments)
136
+ color = Color::YELLOW
137
+ self.echo("> #{title}", color)
138
+ delegate.call(*arguments)
139
+ self.echo("< #{title}", color)
129
140
  end
130
141
 
131
- if '' != stderr
132
- File.symlink('/dev/stderr', File.path(stderr))
142
+ # @param [Array<String>] arguments
143
+ # @return [Array<String>]
144
+ def self.find_paths(*arguments)
145
+ return Dir.glob(arguments.flatten, File::FNM_DOTMATCH).map do |item|
146
+ next File.path(item)
147
+ end.filter do |item|
148
+ next false == %w[. ..].include?(File.basename(item))
149
+ end.uniq
133
150
  end
134
- end
135
151
 
136
- # @param [Array<String>] arguments
137
- def self.clear_path(*arguments, mode: nil)
138
- self.rm(*arguments)
139
- self.mkdir(*arguments, mode: mode)
140
- end
152
+ # @param [Array<String>] arguments
153
+ # @param [String] user
154
+ # @param [String] group
155
+ def self.change_owner(*arguments, user: USER, group: GROUP)
156
+ self.find_paths(*arguments).each do |path|
157
+ FileUtils.chown_R(user, group, path, force: true)
158
+ end
159
+ end
141
160
 
142
- def self.arch_suffix
143
- arch = "#{`apk --print-arch`}".strip
144
- return ARCH_SUFFIX.fetch(arch.to_sym, arch)
145
- end
161
+ # @param [Array<String>] arguments
162
+ def self.change_mode(mode, *arguments)
163
+ self.find_paths(*arguments).each do |path|
164
+ FileUtils.chmod_R(mode, path, force: true)
165
+ end
166
+ end
146
167
 
147
- # @param [String] repository
148
- def self.github_latest_version(repository)
149
- uri = URI("https://api.github.com/repos/#{repository}/releases/latest")
150
- return JSON.parse(Net::HTTP.get(uri))['tag_name']
151
- end
168
+ # @param [Array<String>] arguments
169
+ def self.make_folders(*arguments, mode: nil)
170
+ stack = []
171
+ paths = arguments.map do |path|
172
+ next File.path(path)
173
+ end.uniq
174
+
175
+ paths.each do |path|
176
+ until path == stack.last
177
+ stack << path
178
+ path = File.dirname(path)
179
+ end
180
+ end
152
181
 
153
- # @param [String] uri
154
- # @param [Integer] max_redirect
155
- def self.uri_resolve(uri, max_redirect = 10)
156
- response = Net::HTTP.get_response(URI.parse(uri))
182
+ stack.uniq.each do |path|
183
+ if File.exist?(path) && false == File.directory?(path)
184
+ File.delete(path)
185
+ end
186
+ end
157
187
 
158
- if false == response.is_a?(Net::HTTPRedirection)
159
- return uri
188
+ FileUtils.mkdir_p(paths, mode: mode)
160
189
  end
161
190
 
162
- max_redirect = max_redirect - 1
191
+ # @param [Array<String>] arguments
192
+ def self.remove_paths(*arguments)
193
+ self.find_paths(*arguments).each do |path|
194
+ FileUtils.rm_rf(path)
195
+ end
196
+ end
163
197
 
164
- if 0 == max_redirect
165
- raise('maximum redirect reached')
198
+ # @param [String, Array<String>] source
199
+ # @param [String] target
200
+ def self.move_paths(source, target)
201
+ files = [source].flatten
202
+ FileUtils.mv(self.find_paths(*files), target)
166
203
  end
167
204
 
168
- return self.uri_resolve(response['location'], max_redirect)
169
- end
205
+ # @param [String] uri
206
+ # @param [Integer] max_redirect
207
+ def self.resolve_link(uri, max_redirect = 10)
208
+ response = Net::HTTP.get_response(URI.parse(uri))
170
209
 
171
- # @param [String] uri
172
- # @param [String] file
173
- def self.download_file(uri, file)
174
- uri = self.uri_resolve(uri)
175
- content = Net::HTTP.get(URI(uri))
176
- return File.binwrite(file, content)
177
- end
210
+ if false == response.is_a?(Net::HTTPRedirection)
211
+ return uri
212
+ end
178
213
 
179
- # @param [String] path
180
- # @param [Boolean] verbose
181
- def self.untar(io, path, verbose: false)
182
- # @type [Gem::Package::TarReader] reader
183
- Gem::Package::TarReader.new(io) do |reader|
184
- reader.rewind
185
- reader.each do |entry|
186
- # @type [Gem::Package::TarHeader] header
187
- header = entry.header
188
- mode = header.mode
189
- file = File.join(path, entry.full_name)
190
-
191
- if verbose
192
- self.echo(": #{file}")
193
- end
214
+ max_redirect = max_redirect - 1
194
215
 
195
- if entry.directory?
196
- self.mkdir(file, mode: mode)
197
- next
198
- end
216
+ if 0 == max_redirect
217
+ raise('maximum redirect reached')
218
+ end
199
219
 
200
- if entry.file?
201
- self.mkdir(File.dirname(file))
202
- File.binwrite(file, entry.read)
203
- self.chmod(mode, file)
204
- next
220
+ return self.resolve_link(response['location'], max_redirect)
221
+ end
222
+
223
+ # @param [String] uri
224
+ # @param [String] file
225
+ def self.download_file(uri, file)
226
+ uri = self.resolve_link(uri)
227
+ content = Net::HTTP.get(URI(uri))
228
+ return File.binwrite(file, content)
229
+ end
230
+
231
+ # @param [String] path
232
+ # @param [Boolean] verbose
233
+ def self.untar(io, path, verbose: false)
234
+ Gem::Package::TarReader.new(io) do
235
+
236
+ # @type [Gem::Package::TarReader] reader
237
+ |reader|
238
+ reader.rewind
239
+ reader.each do |entry|
240
+ # @type [Gem::Package::TarHeader] header
241
+ header = entry.header
242
+ mode = header.mode
243
+ file = File.join(path, entry.full_name)
244
+
245
+ if verbose
246
+ self.echo(": #{file}", Color::GREEN)
247
+ end
248
+
249
+ if entry.directory?
250
+ self.make_folders(file, mode: mode)
251
+ next
252
+ end
253
+
254
+ if entry.file?
255
+ self.make_folders(File.dirname(file))
256
+ File.binwrite(file, entry.read)
257
+ self.change_mode(mode, file)
258
+ next
259
+ end
205
260
  end
206
261
  end
207
262
  end
208
- end
209
263
 
210
- # @param [String] file
211
- # @param [String] path
212
- # @param [Boolean] verbose
213
- def self.ungzip(file, path, verbose: false)
214
- # @type [Zlib::GzipReader] reader
215
- Zlib::GzipReader.open(file) do |reader|
216
- self.untar(reader, path, verbose: verbose)
264
+ # @param [String] file
265
+ # @param [String] path
266
+ # @param [Boolean] verbose
267
+ def self.ungzip(file, path, verbose: false)
268
+ Zlib::GzipReader.open(file) do
269
+
270
+ # @type [Zlib::GzipReader] reader
271
+ |reader|
272
+ self.untar(reader, path, verbose: verbose)
273
+ end
217
274
  end
218
- end
219
275
 
220
- # @param [String] path
221
- # @param [Boolean] verbose
222
- def self.tar(path, verbose: false)
223
- io = StringIO.new('')
224
- offset = path.size + 1
225
-
226
- # @type [Gem::Package::TarWriter] writer
227
- Gem::Package::TarWriter.new(io) do |writer|
228
- # @type [String] file
229
- self.path(File.join(path, '**/*')).each do |name|
230
- mode = File.stat(name).mode
231
- file = name.slice(offset ..)
232
-
233
- if verbose
234
- self.echo(": #{file}")
235
- end
276
+ # @param [String] path
277
+ # @param [Boolean] verbose
278
+ def self.tar(path, verbose: false)
279
+ io = StringIO.new('')
280
+ offset = path.size + 1
236
281
 
237
- if File.directory?(name)
238
- writer.mkdir(file, mode)
239
- next
240
- end
282
+ Gem::Package::TarWriter.new(io) do
283
+
284
+ # @type [Gem::Package::TarWriter] writer
285
+ |writer|
286
+ self.find_paths(File.join(path, '**/*')).each do |name|
287
+ mode = File.stat(name).mode
288
+ file = name.slice(offset ..)
241
289
 
242
- if File.file?(name)
243
- writer.add_file(file, mode) do |stream|
244
- stream.write(File.binread(name))
290
+ if verbose
291
+ self.echo(": #{file}", Color::GREEN)
292
+ end
293
+
294
+ if File.directory?(name)
295
+ writer.mkdir(file, mode)
296
+ next
297
+ end
298
+
299
+ if File.file?(name)
300
+ writer.add_file(file, mode) do |stream|
301
+ stream.write(File.binread(name))
302
+ end
303
+ next
245
304
  end
246
- next
247
305
  end
248
306
  end
307
+
308
+ io.rewind
309
+ return io.string
249
310
  end
250
311
 
251
- io.rewind
252
- return io.string
253
- end
312
+ # @param [String] file
313
+ # @param [String] path
314
+ # @param [Boolean] verbose
315
+ def self.gzip(file, path, verbose: false)
316
+ Zlib::GzipWriter.open(file, Zlib::BEST_COMPRESSION) do
317
+
318
+ # @type [Zlib::GzipWriter] writer
319
+ |writer|
320
+ writer.write(self.tar(path, verbose: verbose))
321
+ end
322
+ end
323
+
324
+ # @param [Integer] uid
325
+ # @param [Integer] gid
326
+ def self.update_user(uid: 500, gid: 500)
327
+ self.run('deluser', USER, force: true)
328
+ self.run('delgroup', GROUP, force: true)
329
+ self.run('addgroup', { system: true, gid: ENV.fetch('DOCKER_CORE_GID', gid) }, GROUP)
330
+ self.run('adduser', { system: true, 'disabled-password': true, 'no-create-home': true, ingroup: GROUP, gecos: USER, shell: '/bin/bash', uid: ENV.fetch('DOCKER_CORE_UID', uid) }, USER)
331
+ end
332
+
333
+ # @param [String] stdout
334
+ # @param [String] stderr
335
+ def self.link_logs(stdout: '', stderr: '')
336
+ if '' != stdout
337
+ File.symlink('/dev/stdout', File.path(stdout))
338
+ end
339
+
340
+ if '' != stderr
341
+ File.symlink('/dev/stderr', File.path(stderr))
342
+ end
343
+ end
344
+
345
+ # @param [Array<String>] arguments
346
+ def self.clear_folders(*arguments, mode: nil)
347
+ self.remove_paths(*arguments)
348
+ self.make_folders(*arguments, mode: mode)
349
+ end
350
+
351
+ def self.architecture
352
+ hash = { x86: '386', x86_64: 'amd64', armhf: 'armv6', armv7l: 'armv7', aarch64: 'arm64' }
353
+ machine = "#{Etc.uname[:machine]}"
354
+ return hash.fetch(machine.to_sym, machine)
355
+ end
254
356
 
255
- # @param [String] file
256
- # @param [String] path
257
- # @param [Boolean] verbose
258
- def self.gzip(file, path, verbose: false)
259
- # @type [Zlib::GzipWriter] writer
260
- Zlib::GzipWriter.open(file, Zlib::BEST_COMPRESSION) do |writer|
261
- writer.write(self.tar(path, verbose: verbose))
357
+ # @param [String] repository
358
+ def self.github_latest_version(repository)
359
+ uri = URI("https://api.github.com/repos/#{repository}/releases/latest")
360
+ return JSON.parse(Net::HTTP.get(uri))['tag_name']
262
361
  end
263
362
  end
264
363
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: docker_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.15
4
+ version: 0.0.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - agrozyme
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-07-13 00:00:00.000000000 Z
11
+ date: 2021-08-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fileutils
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: thor
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: zlib
43
57
  requirement: !ruby/object:Gem::Requirement