docker_core 0.0.16 → 0.0.17

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