kanrisuru 0.1.0 → 0.2.1

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 (81) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +17 -0
  3. data/.rubocop.yml +47 -0
  4. data/.rubocop_todo.yml +0 -0
  5. data/CHANGELOG.md +0 -0
  6. data/Gemfile +2 -5
  7. data/LICENSE.txt +1 -1
  8. data/README.md +143 -7
  9. data/Rakefile +5 -3
  10. data/bin/console +4 -3
  11. data/kanrisuru.gemspec +21 -12
  12. data/lib/kanrisuru.rb +41 -2
  13. data/lib/kanrisuru/command.rb +99 -0
  14. data/lib/kanrisuru/core.rb +53 -0
  15. data/lib/kanrisuru/core/archive.rb +154 -0
  16. data/lib/kanrisuru/core/disk.rb +302 -0
  17. data/lib/kanrisuru/core/file.rb +332 -0
  18. data/lib/kanrisuru/core/find.rb +108 -0
  19. data/lib/kanrisuru/core/group.rb +97 -0
  20. data/lib/kanrisuru/core/ip.rb +1032 -0
  21. data/lib/kanrisuru/core/mount.rb +138 -0
  22. data/lib/kanrisuru/core/path.rb +140 -0
  23. data/lib/kanrisuru/core/socket.rb +168 -0
  24. data/lib/kanrisuru/core/stat.rb +104 -0
  25. data/lib/kanrisuru/core/stream.rb +121 -0
  26. data/lib/kanrisuru/core/system.rb +348 -0
  27. data/lib/kanrisuru/core/transfer.rb +203 -0
  28. data/lib/kanrisuru/core/user.rb +198 -0
  29. data/lib/kanrisuru/logger.rb +8 -0
  30. data/lib/kanrisuru/mode.rb +277 -0
  31. data/lib/kanrisuru/os_package.rb +235 -0
  32. data/lib/kanrisuru/remote.rb +10 -0
  33. data/lib/kanrisuru/remote/cluster.rb +95 -0
  34. data/lib/kanrisuru/remote/cpu.rb +68 -0
  35. data/lib/kanrisuru/remote/env.rb +33 -0
  36. data/lib/kanrisuru/remote/file.rb +354 -0
  37. data/lib/kanrisuru/remote/fstab.rb +412 -0
  38. data/lib/kanrisuru/remote/host.rb +191 -0
  39. data/lib/kanrisuru/remote/memory.rb +19 -0
  40. data/lib/kanrisuru/remote/os.rb +87 -0
  41. data/lib/kanrisuru/result.rb +78 -0
  42. data/lib/kanrisuru/template.rb +32 -0
  43. data/lib/kanrisuru/util.rb +40 -0
  44. data/lib/kanrisuru/util/bits.rb +203 -0
  45. data/lib/kanrisuru/util/fs_mount_opts.rb +655 -0
  46. data/lib/kanrisuru/util/os_family.rb +213 -0
  47. data/lib/kanrisuru/util/signal.rb +161 -0
  48. data/lib/kanrisuru/version.rb +3 -1
  49. data/spec/functional/core/archive_spec.rb +228 -0
  50. data/spec/functional/core/disk_spec.rb +80 -0
  51. data/spec/functional/core/file_spec.rb +341 -0
  52. data/spec/functional/core/find_spec.rb +52 -0
  53. data/spec/functional/core/group_spec.rb +65 -0
  54. data/spec/functional/core/ip_spec.rb +71 -0
  55. data/spec/functional/core/path_spec.rb +93 -0
  56. data/spec/functional/core/socket_spec.rb +31 -0
  57. data/spec/functional/core/stat_spec.rb +98 -0
  58. data/spec/functional/core/stream_spec.rb +99 -0
  59. data/spec/functional/core/system_spec.rb +96 -0
  60. data/spec/functional/core/transfer_spec.rb +108 -0
  61. data/spec/functional/core/user_spec.rb +76 -0
  62. data/spec/functional/os_package_spec.rb +75 -0
  63. data/spec/functional/remote/cluster_spec.rb +45 -0
  64. data/spec/functional/remote/cpu_spec.rb +41 -0
  65. data/spec/functional/remote/env_spec.rb +36 -0
  66. data/spec/functional/remote/fstab_spec.rb +76 -0
  67. data/spec/functional/remote/host_spec.rb +68 -0
  68. data/spec/functional/remote/memory_spec.rb +29 -0
  69. data/spec/functional/remote/os_spec.rb +63 -0
  70. data/spec/functional/remote/remote_file_spec.rb +180 -0
  71. data/spec/helper/test_hosts.rb +68 -0
  72. data/spec/hosts.json +92 -0
  73. data/spec/spec_helper.rb +11 -3
  74. data/spec/unit/fstab_spec.rb +22 -0
  75. data/spec/unit/kanrisuru_spec.rb +9 -0
  76. data/spec/unit/mode_spec.rb +183 -0
  77. data/spec/unit/template_spec.rb +13 -0
  78. data/spec/unit/util_spec.rb +177 -0
  79. data/spec/zz_reboot_spec.rb +46 -0
  80. metadata +136 -13
  81. data/spec/kanrisuru_spec.rb +0 -9
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'core/path'
4
+ require_relative 'core/system'
5
+ require_relative 'core/disk'
6
+ require_relative 'core/mount'
7
+ require_relative 'core/stat'
8
+ require_relative 'core/find'
9
+ require_relative 'core/file'
10
+ require_relative 'core/group'
11
+ require_relative 'core/user'
12
+ require_relative 'core/archive'
13
+ require_relative 'core/stream'
14
+ require_relative 'core/transfer'
15
+ require_relative 'core/ip'
16
+ require_relative 'core/socket'
17
+
18
+ module Kanrisuru
19
+ module Remote
20
+ class Host
21
+ os_include Kanrisuru::Core::Path
22
+ os_include Kanrisuru::Core::System
23
+ os_include Kanrisuru::Core::Disk
24
+ os_include Kanrisuru::Core::Mount
25
+ os_include Kanrisuru::Core::Stat
26
+ os_include Kanrisuru::Core::Find
27
+ os_include Kanrisuru::Core::File
28
+ os_include Kanrisuru::Core::Group
29
+ os_include Kanrisuru::Core::User
30
+ os_include Kanrisuru::Core::Archive
31
+ os_include Kanrisuru::Core::Stream
32
+ os_include Kanrisuru::Core::Transfer
33
+ os_include Kanrisuru::Core::IP
34
+ os_include Kanrisuru::Core::Socket
35
+ end
36
+
37
+ class Cluster
38
+ os_collection Kanrisuru::Core::Path
39
+ os_collection Kanrisuru::Core::System
40
+ os_collection Kanrisuru::Core::Disk
41
+ os_collection Kanrisuru::Core::Mount
42
+ os_collection Kanrisuru::Core::Stat
43
+ os_collection Kanrisuru::Core::File
44
+ os_collection Kanrisuru::Core::Group
45
+ os_collection Kanrisuru::Core::User
46
+ os_collection Kanrisuru::Core::Archive
47
+ os_collection Kanrisuru::Core::Stream
48
+ os_collection Kanrisuru::Core::Transfer
49
+ os_collection Kanrisuru::Core::IP
50
+ os_collection Kanrisuru::Core::Socket
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,154 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kanrisuru
4
+ module Core
5
+ module Archive
6
+ extend OsPackage::Define
7
+
8
+ os_define :linux, :tar
9
+
10
+ FilePath = Struct.new(:path)
11
+
12
+ def tar(action, file, opts = {})
13
+ compress = opts[:compress]
14
+ paths = opts[:paths]
15
+ exclude = opts[:exclude]
16
+ directory = opts[:directory]
17
+
18
+ command = Kanrisuru::Command.new('tar --restrict')
19
+
20
+ directory = realpath(directory, strip: true).path if directory
21
+ command.append_arg('-C', directory)
22
+ command.append_arg('-f', file)
23
+
24
+ set_compression(command, compress) if compress
25
+
26
+ case action
27
+ when 'list'
28
+ command.append_flag('-t')
29
+ command.append_arg('--occurrence', opts[:occurrence])
30
+ command.append_flag('--label', opts[:label])
31
+ command.append_flag('--multi-volume', opts[:multi_volume])
32
+
33
+ execute_shell(command)
34
+ Kanrisuru::Result.new(command) do |cmd|
35
+ items = cmd.to_a
36
+
37
+ items.map do |item|
38
+ FilePath.new(item)
39
+ end
40
+ end
41
+ when 'extract', 'get'
42
+ command.append_flag('-x')
43
+ command.append_arg('--occurrence', opts[:occurrence])
44
+ command.append_flag('--no-same-owner', opts[:no_same_owner])
45
+ command.append_flag('--no-same-permissions', opts[:no_same_permissions])
46
+ command.append_flag('--no-selinux', opts[:no_selinux])
47
+ command.append_flag('--no-xattrs', opts[:no_xattrs])
48
+ command.append_flag('--preserve-permissions', opts[:preserve_permissions])
49
+ command.append_flag('--same-owner', opts[:same_owners])
50
+ command.append_flag('--multi-volume', opts[:multi_volume])
51
+ command.append_flag('--label', opts[:label])
52
+ command.append_flag('--one-file-system ', opts[:one_file_system])
53
+ command.append_flag('--keep-old-files', opts[:keep_old_files])
54
+ command.append_flag('--skip-old-files', opts[:skip_old_files])
55
+ command.append_flag('--overwrite', opts[:overwrite])
56
+ command.append_flag('--overwrite-dir', opts[:overwrite_dir])
57
+ command.append_flag('--unlink-first', opts[:unlink_first])
58
+ command.append_flag('--recursive-unlink', opts[:recursive_unlink])
59
+
60
+ if Kanrisuru::Util.present?(paths)
61
+ paths = paths.instance_of(String) ? [paths] : paths
62
+ command << paths.join(' ')
63
+ end
64
+
65
+ execute_shell(command)
66
+ Kanrisuru::Result.new(command)
67
+ when 'create'
68
+ command.append_flag('-c')
69
+ command.append_flag('--multi-volume', opts[:multi_volume])
70
+
71
+ if Kanrisuru::Util.present?(exclude)
72
+ exclude = exclude.instance_of?(String) ? [exclude] : exclude
73
+ command.append_arg('--exclude', exclude.join(' '))
74
+ end
75
+
76
+ if Kanrisuru::Util.present?(paths)
77
+ paths = paths.instance_of?(String) ? [paths] : paths
78
+ command << paths.join(' ')
79
+ end
80
+
81
+ execute_shell(command)
82
+
83
+ Kanrisuru::Result.new(command)
84
+ when 'append'
85
+ command.append_flag('-r')
86
+
87
+ if Kanrisuru::Util.present?(paths)
88
+ paths = paths.instance_of?(String) ? [paths] : paths
89
+ command << paths.join(' ')
90
+ end
91
+
92
+ execute_shell(command)
93
+ Kanrisuru::Result.new(command)
94
+ when 'catenate', 'concat'
95
+ command.append_flag('-A')
96
+
97
+ if Kanrisuru::Util.present?(paths)
98
+ paths = paths.instance_of?(String) ? [paths] : paths
99
+ command << paths.join(' ')
100
+ end
101
+
102
+ execute_shell(command)
103
+ Kanrisuru::Result.new(command)
104
+ when 'update'
105
+ command.append_flag('-u')
106
+
107
+ if Kanrisuru::Util.present?(paths)
108
+ paths = paths.instance_of?(String) ? [paths] : paths
109
+ command << paths.join(' ')
110
+ end
111
+
112
+ execute_shell(command)
113
+ Kanrisuru::Result.new(command)
114
+ when 'diff', 'compare'
115
+ command.append_flag('-d')
116
+ command.append_arg('--occurrence', opts[:occurrence])
117
+
118
+ execute_shell(command)
119
+ Kanrisuru::Result.new(command)
120
+ when 'delete'
121
+ command.append_flag('--delete')
122
+ command.append_arg('--occurrence', opts[:occurrence])
123
+
124
+ if Kanrisuru::Util.present?(paths)
125
+ paths = paths.instance_of?(String) ? [paths] : paths
126
+ command << paths.join(' ')
127
+ end
128
+
129
+ execute_shell(command)
130
+ Kanrisuru::Result.new(command)
131
+ else
132
+ raise ArgumentError, 'Invalid argument action'
133
+ end
134
+ end
135
+
136
+ private
137
+
138
+ def set_compression(command, compress)
139
+ case compress
140
+ when 'bzip2'
141
+ command.append_flag('-j')
142
+ when 'xz'
143
+ command.append_flag('-J')
144
+ when 'gzip'
145
+ command.append_flag('-z')
146
+ when 'lzma'
147
+ command.append_flag('--lzma')
148
+ else
149
+ raise ArgumentError, "Invalid copmression program: #{compress}"
150
+ end
151
+ end
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,302 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module Kanrisuru
6
+ module Core
7
+ module Disk
8
+ extend OsPackage::Define
9
+
10
+ os_define :linux, :df
11
+ os_define :linux, :du
12
+ os_define :linux, :blkid
13
+ os_define :linux, :lsblk
14
+
15
+ DiskUsage = Struct.new(:fsize, :path)
16
+ DiskFree = Struct.new(:file_system, :type, :total, :used, :capacity, :mount)
17
+ LsblkDevice = Struct.new(
18
+ :name, :maj_dev, :min_dev, :removable_device, :readonly_device, :owner, :group,
19
+ :mode, :fsize, :type, :mount_point, :fs_type, :uuid, :children
20
+ )
21
+
22
+ BlkidDevice = Struct.new(
23
+ :name, :label, :uuid, :type, :uuid_sub, :label_fatboot, :version, :usage,
24
+ :part_uuid, :part_entry_scheme, :part_entry_uuid, :part_entry_type,
25
+ :part_entry_number, :part_entry_offset, :part_entry_size, :part_entry_disk
26
+ )
27
+
28
+ def du(opts = {})
29
+ path = opts[:path]
30
+ convert = opts[:convert]
31
+
32
+ command = Kanrisuru::Command.new('du')
33
+ command.append_arg('-s', path)
34
+ command | "awk '{print $1, $2}'"
35
+
36
+ execute(command)
37
+
38
+ Kanrisuru::Result.new(command) do |cmd|
39
+ string = cmd.to_s
40
+ rows = string.split("\n")
41
+
42
+ rows.map do |row|
43
+ values = row.split
44
+ size = convert ? Kanrisuru::Util::Bits.convert_bytes(values[0], :byte, convert) : values[0]
45
+
46
+ DiskUsage.new(size, values[1])
47
+ end
48
+ end
49
+ end
50
+
51
+ def df(opts = {})
52
+ path = opts[:path]
53
+ inodes = opts[:inodes]
54
+
55
+ command = Kanrisuru::Command.new('df')
56
+
57
+ command.append_flag('-PT')
58
+ command.append_flag('-i', inodes)
59
+
60
+ command << path if Kanrisuru::Util.present?(path)
61
+ command | "awk '{print $1, $2, $3, $5, $6, $7}'"
62
+
63
+ execute(command)
64
+
65
+ Kanrisuru::Result.new(command) do |cmd|
66
+ items = []
67
+ rows = cmd.to_a
68
+ rows.each.with_index do |row, index|
69
+ next if index.zero?
70
+
71
+ values = row.split
72
+
73
+ items << DiskFree.new(
74
+ values[0],
75
+ values[1],
76
+ values[2].to_i,
77
+ values[3].to_i,
78
+ values[4].to_i,
79
+ values[5]
80
+ )
81
+ end
82
+ items
83
+ end
84
+ end
85
+
86
+ def blkid(opts = {})
87
+ label = opts[:label]
88
+ uuid = opts[:uuid]
89
+ device = opts[:device]
90
+
91
+ mode = ''
92
+ command = Kanrisuru::Command.new('blkid')
93
+
94
+ if Kanrisuru::Util.present?(label) || Kanrisuru::Util.present?(uuid)
95
+ mode = 'search'
96
+ command.append_arg('-L', opts[:label])
97
+ command.append_arg('-U', opts[:uuid])
98
+ elsif Kanrisuru::Util.present?(device)
99
+ mode = 'device'
100
+ command.append_arg('-po', 'export')
101
+ command << device
102
+ else
103
+ mode = 'list'
104
+ command.append_arg('-o', 'export')
105
+ end
106
+
107
+ execute_shell(command)
108
+
109
+ Kanrisuru::Result.new(command) do |cmd|
110
+ case mode
111
+ when 'search'
112
+ cmd.to_s
113
+ when 'device'
114
+ lines = cmd.to_a
115
+
116
+ ## Only gets 1 device
117
+ devices = blkid_devices(lines)
118
+ devices[0]
119
+ else
120
+ lines = cmd.to_a
121
+ blkid_devices(lines)
122
+ end
123
+ end
124
+ end
125
+
126
+ def lsblk(opts = {})
127
+ all = opts[:all]
128
+ nodeps = opts[:nodeps]
129
+ paths = opts[:paths]
130
+
131
+ command = Kanrisuru::Command.new('lsblk')
132
+
133
+ version = lsblk_version
134
+
135
+ ## lsblk after version 2.26 handles json parsing.
136
+ ## TODO: parse nested children for earlier version of lsblk
137
+ if version >= 2.27
138
+ command.append_flag('--json') if version >= 2.27
139
+ else
140
+ command.append_flag('-i')
141
+ command.append_flag('-P')
142
+ command.append_flag('--noheadings')
143
+ end
144
+
145
+ command.append_flag('-a', all)
146
+ command.append_flag('-p', paths)
147
+ command.append_flag('-p', nodeps)
148
+
149
+ command.append_arg('-o', 'NAME,FSTYPE,MAJ:MIN,MOUNTPOINT,SIZE,UUID,RO,RM,OWNER,GROUP,MODE,TYPE')
150
+ execute(command)
151
+
152
+ Kanrisuru::Result.new(command) do |cmd|
153
+ if version >= 2.27
154
+ result = cmd.to_json
155
+ devices = result['blockdevices']
156
+ build_lsblk_devices_json(devices)
157
+ else
158
+ build_lsblk_devices_text(cmd.to_a)
159
+ end
160
+ end
161
+ end
162
+
163
+ private
164
+
165
+ def blkid_devices(lines)
166
+ devices = []
167
+ current_device = nil
168
+
169
+ lines.each do |line|
170
+ value = line.split('=')[1]
171
+
172
+ if line =~ /^DEVNAME=/
173
+ current_device = BlkidDevice.new(value)
174
+ elsif line =~ /^UUID=/
175
+ current_device.uuid = value
176
+ elsif line =~ /^LABEL=/
177
+ current_device.label = value
178
+ elsif line =~ /^TYPE=/
179
+ current_device.type = value
180
+ elsif line =~ /^LABEL_FATBOOT=/
181
+ current_device.label_fatboot = value
182
+ elsif line =~ /^PARTUUID=/
183
+ current_device.part_uuid = value
184
+ elsif line =~ /^UUID_SUB=/
185
+ current_device.uuid_sub = value
186
+ elsif line =~ /^USAGE=/
187
+ current_device.usage = value
188
+ elsif line =~ /^VERSION=/
189
+ current_device.version = value.to_f
190
+ elsif line =~ /^PART_ENTRY_SCHEME=/
191
+ current_device.part_entry_scheme = value
192
+ elsif line =~ /^PART_ENTRY_UUID=/
193
+ current_device.part_entry_uuid = value
194
+ elsif line =~ /^PART_ENTRY_DISK=/
195
+ current_device.part_entry_disk = value
196
+ elsif line =~ /^PART_ENTRY_NUMBER=/
197
+ current_device.part_entry_number = value.to_i
198
+ elsif line =~ /^PART_ENTRY_OFFSET=/
199
+ current_device.part_entry_offset = value.to_i
200
+ elsif line =~ /^PART_ENTRY_SIZE=/
201
+ current_device.part_entry_size = value.to_i
202
+ elsif line =~ /^PART_ENTRY_TYPE=/
203
+ current_device.part_entry_type = value
204
+ elsif Kanrisuru::Util.blank?(line)
205
+ devices << current_device
206
+ current_device = nil
207
+ end
208
+ end
209
+
210
+ devices << current_device if Kanrisuru::Util.present?(current_device)
211
+ devices
212
+ end
213
+
214
+ def lsblk_version
215
+ command = Kanrisuru::Command.new('lsblk --version')
216
+ execute(command)
217
+
218
+ version = 0.00
219
+ regex = Regexp.new(/\d+(?:[,.]\d+)?/)
220
+
221
+ raise 'lsblk command not found' if command.failure?
222
+
223
+ version = command.to_s.scan(regex)[0].to_f unless regex.match(command.to_s).nil?
224
+
225
+ version
226
+ end
227
+
228
+ def build_lsblk_devices_text(lines)
229
+ devices = []
230
+
231
+ lines.each do |line|
232
+ values = line.split
233
+
234
+ current_device = LsblkDevice.new
235
+
236
+ values.each do |value|
237
+ key, value = value.split('=')
238
+ value = value.gsub(/"/, '')
239
+
240
+ case key
241
+ when 'NAME'
242
+ current_device.name = value
243
+ when 'FSTYPE'
244
+ current_device.fs_type = value
245
+ when 'MAJ:MIN'
246
+ maj, min = value.split(':')
247
+ current_device.maj_dev = maj
248
+ current_device.min_dev = min
249
+ when 'MOUNTPOINT'
250
+ current_device.mount_point = value
251
+ when 'SIZE'
252
+ current_device.fsize = value
253
+ when 'UUID'
254
+ current_device.uuid = value
255
+ when 'RO'
256
+ current_device.readonly_device = value
257
+ when 'RM'
258
+ current_device.removable_device = value
259
+ when 'OWNER'
260
+ current_device.owner = value
261
+ when 'GROUP'
262
+ current_device.group = value
263
+ when 'MODE'
264
+ current_device.mode = value
265
+ when 'TYPE'
266
+ current_device.type = value
267
+ end
268
+ end
269
+
270
+ devices << current_device
271
+ end
272
+
273
+ devices
274
+ end
275
+
276
+ def build_lsblk_devices_json(devices)
277
+ devices.map do |device|
278
+ children = (build_lsblk_devices_json(device['children']) if device.key?('children'))
279
+
280
+ maj_min = device['maj:min']
281
+
282
+ LsblkDevice.new(
283
+ device['name'],
284
+ maj_min ? maj_min.split(':')[0] : nil,
285
+ maj_min ? maj_min.split(':')[1] : nil,
286
+ device['rm'],
287
+ device['ro'],
288
+ device['owner'],
289
+ device['group'],
290
+ device['mode'],
291
+ device['size'],
292
+ device['type'],
293
+ device['mountpoint'],
294
+ device['fstype'],
295
+ device['uuid'],
296
+ children
297
+ )
298
+ end
299
+ end
300
+ end
301
+ end
302
+ end