kanrisuru 0.1.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +17 -0
- data/.rubocop.yml +47 -0
- data/.rubocop_todo.yml +0 -0
- data/CHANGELOG.md +0 -0
- data/Gemfile +2 -5
- data/LICENSE.txt +1 -1
- data/README.md +143 -7
- data/Rakefile +5 -3
- data/bin/console +4 -3
- data/kanrisuru.gemspec +21 -12
- data/lib/kanrisuru.rb +41 -2
- data/lib/kanrisuru/command.rb +99 -0
- data/lib/kanrisuru/core.rb +53 -0
- data/lib/kanrisuru/core/archive.rb +154 -0
- data/lib/kanrisuru/core/disk.rb +302 -0
- data/lib/kanrisuru/core/file.rb +332 -0
- data/lib/kanrisuru/core/find.rb +108 -0
- data/lib/kanrisuru/core/group.rb +97 -0
- data/lib/kanrisuru/core/ip.rb +1032 -0
- data/lib/kanrisuru/core/mount.rb +138 -0
- data/lib/kanrisuru/core/path.rb +140 -0
- data/lib/kanrisuru/core/socket.rb +168 -0
- data/lib/kanrisuru/core/stat.rb +104 -0
- data/lib/kanrisuru/core/stream.rb +121 -0
- data/lib/kanrisuru/core/system.rb +348 -0
- data/lib/kanrisuru/core/transfer.rb +203 -0
- data/lib/kanrisuru/core/user.rb +198 -0
- data/lib/kanrisuru/logger.rb +8 -0
- data/lib/kanrisuru/mode.rb +277 -0
- data/lib/kanrisuru/os_package.rb +235 -0
- data/lib/kanrisuru/remote.rb +10 -0
- data/lib/kanrisuru/remote/cluster.rb +95 -0
- data/lib/kanrisuru/remote/cpu.rb +68 -0
- data/lib/kanrisuru/remote/env.rb +33 -0
- data/lib/kanrisuru/remote/file.rb +354 -0
- data/lib/kanrisuru/remote/fstab.rb +412 -0
- data/lib/kanrisuru/remote/host.rb +191 -0
- data/lib/kanrisuru/remote/memory.rb +19 -0
- data/lib/kanrisuru/remote/os.rb +87 -0
- data/lib/kanrisuru/result.rb +78 -0
- data/lib/kanrisuru/template.rb +32 -0
- data/lib/kanrisuru/util.rb +40 -0
- data/lib/kanrisuru/util/bits.rb +203 -0
- data/lib/kanrisuru/util/fs_mount_opts.rb +655 -0
- data/lib/kanrisuru/util/os_family.rb +213 -0
- data/lib/kanrisuru/util/signal.rb +161 -0
- data/lib/kanrisuru/version.rb +3 -1
- data/spec/functional/core/archive_spec.rb +228 -0
- data/spec/functional/core/disk_spec.rb +80 -0
- data/spec/functional/core/file_spec.rb +341 -0
- data/spec/functional/core/find_spec.rb +52 -0
- data/spec/functional/core/group_spec.rb +65 -0
- data/spec/functional/core/ip_spec.rb +71 -0
- data/spec/functional/core/path_spec.rb +93 -0
- data/spec/functional/core/socket_spec.rb +31 -0
- data/spec/functional/core/stat_spec.rb +98 -0
- data/spec/functional/core/stream_spec.rb +99 -0
- data/spec/functional/core/system_spec.rb +96 -0
- data/spec/functional/core/transfer_spec.rb +108 -0
- data/spec/functional/core/user_spec.rb +76 -0
- data/spec/functional/os_package_spec.rb +75 -0
- data/spec/functional/remote/cluster_spec.rb +45 -0
- data/spec/functional/remote/cpu_spec.rb +41 -0
- data/spec/functional/remote/env_spec.rb +36 -0
- data/spec/functional/remote/fstab_spec.rb +76 -0
- data/spec/functional/remote/host_spec.rb +68 -0
- data/spec/functional/remote/memory_spec.rb +29 -0
- data/spec/functional/remote/os_spec.rb +63 -0
- data/spec/functional/remote/remote_file_spec.rb +180 -0
- data/spec/helper/test_hosts.rb +68 -0
- data/spec/hosts.json +92 -0
- data/spec/spec_helper.rb +11 -3
- data/spec/unit/fstab_spec.rb +22 -0
- data/spec/unit/kanrisuru_spec.rb +9 -0
- data/spec/unit/mode_spec.rb +183 -0
- data/spec/unit/template_spec.rb +13 -0
- data/spec/unit/util_spec.rb +177 -0
- data/spec/zz_reboot_spec.rb +46 -0
- metadata +136 -13
- data/spec/kanrisuru_spec.rb +0 -9
@@ -0,0 +1,138 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kanrisuru
|
4
|
+
module Core
|
5
|
+
module Mount
|
6
|
+
extend OsPackage::Define
|
7
|
+
|
8
|
+
os_define :linux, :mount
|
9
|
+
os_define :linux, :umount
|
10
|
+
|
11
|
+
def mount(opts = {})
|
12
|
+
type = opts[:type]
|
13
|
+
all = opts[:all]
|
14
|
+
device = opts[:device]
|
15
|
+
directory = opts[:directory]
|
16
|
+
|
17
|
+
bind_old = opts[:bind_old]
|
18
|
+
bind_new = opts[:bind_new]
|
19
|
+
rbind_old = opts[:rbind_old]
|
20
|
+
rbind_new = opts[:rbind_new]
|
21
|
+
move_old = opts[:move_old]
|
22
|
+
move_new = opts[:move_new]
|
23
|
+
fs_opts = opts[:fs_opts]
|
24
|
+
|
25
|
+
command = Kanrisuru::Command.new('mount')
|
26
|
+
|
27
|
+
if Kanrisuru::Util.present?(bind_old) && Kanrisuru::Util.present?(bind_new)
|
28
|
+
command.append_flag('--bind')
|
29
|
+
command << bind_old
|
30
|
+
command << bind_new
|
31
|
+
elsif Kanrisuru::Util.present?(rbind_old) && Kanrisuru::Util.present?(rbind_new)
|
32
|
+
command.append_flag('--rbind')
|
33
|
+
command << rbind_old
|
34
|
+
command << rbind_new
|
35
|
+
elsif Kanrisuru::Util.present?(move_old) && Kanrisuru::Util.present?(move_new)
|
36
|
+
command.append_flag('--move')
|
37
|
+
command << move_old
|
38
|
+
command << move_new
|
39
|
+
else
|
40
|
+
command.append_arg('-L', opts[:label])
|
41
|
+
command.append_arg('-U', opts[:uuid])
|
42
|
+
command.append_flag('-n', opts[:no_mtab])
|
43
|
+
command.append_flag('-f', opts[:fake])
|
44
|
+
command.append_flag('-i', opts[:internal_only])
|
45
|
+
command.append_flag('-s', opts[:sloppy])
|
46
|
+
|
47
|
+
command.append_flag('--no-mtab', opts[:no_mtab])
|
48
|
+
command.append_flag('--no-canonicalizeb', opts[:no_canonicalize])
|
49
|
+
|
50
|
+
fs_options = nil
|
51
|
+
if Kanrisuru::Util.present?(type)
|
52
|
+
add_type(command, type)
|
53
|
+
fs_options = Kanrisuru::Remote::Fstab::Options.new(type, fs_opts) if fs_opts
|
54
|
+
elsif fs_opts
|
55
|
+
fs_options = Kanrisuru::Remote::Fstab::Options.new('common', fs_opts)
|
56
|
+
end
|
57
|
+
|
58
|
+
if Kanrisuru::Util.present?(all)
|
59
|
+
command.append_flag('-a')
|
60
|
+
add_test_opts(command, opts[:test_opts], type)
|
61
|
+
else
|
62
|
+
command.append_arg('-o', fs_options.to_s)
|
63
|
+
|
64
|
+
command << device if Kanrisuru::Util.present?(device)
|
65
|
+
command << directory if Kanrisuru::Util.present?(directory)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
execute_shell(command)
|
70
|
+
Kanrisuru::Result.new(command)
|
71
|
+
end
|
72
|
+
|
73
|
+
def umount(opts = {})
|
74
|
+
all = opts[:all]
|
75
|
+
type = opts[:type]
|
76
|
+
command = Kanrisuru::Command.new('umount')
|
77
|
+
|
78
|
+
if Kanrisuru::Util.present?(all)
|
79
|
+
command.append_flag('-a')
|
80
|
+
add_type(command, type)
|
81
|
+
add_test_opts(command, opts[:test_opts], type)
|
82
|
+
end
|
83
|
+
|
84
|
+
command.append_flag('--fake', opts[:fake])
|
85
|
+
command.append_flag('--no-canonicalize', opts[:no_canonicalize])
|
86
|
+
command.append_flag('-n', opts[:no_mtab])
|
87
|
+
command.append_flag('-r', opts[:fail_remount_readonly])
|
88
|
+
command.append_flag('-d', opts[:free_loopback])
|
89
|
+
|
90
|
+
command.append_flag('-l', opts[:lazy])
|
91
|
+
command.append_flag('-f', opts[:force])
|
92
|
+
|
93
|
+
execute_shell(command)
|
94
|
+
|
95
|
+
Kanrisuru::Result.new(command)
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
def add_type(command, type)
|
101
|
+
return unless Kanrisuru::Util.present?(type)
|
102
|
+
|
103
|
+
test_types = nil
|
104
|
+
|
105
|
+
if type.include?(',')
|
106
|
+
if type.include?('no')
|
107
|
+
test_types = type.gsub('no', '')
|
108
|
+
test_types = test_types.split(',')
|
109
|
+
else
|
110
|
+
test_types = type.split(',')
|
111
|
+
end
|
112
|
+
else
|
113
|
+
test_types = [type]
|
114
|
+
end
|
115
|
+
|
116
|
+
test_types.each do |t|
|
117
|
+
device_opts = Kanrisuru::Util::FsMountOpts.get_device(t)
|
118
|
+
raise ArugmentError, "Invalid fstype: #{t}" unless device_opts
|
119
|
+
end
|
120
|
+
|
121
|
+
command.append_arg('-t', type)
|
122
|
+
end
|
123
|
+
|
124
|
+
def add_test_opts(command, test_opts, type)
|
125
|
+
return unless Kanrisuru::Util.present?(test_opts)
|
126
|
+
|
127
|
+
test_options =
|
128
|
+
if Kanrisuru::Util.present?(type)
|
129
|
+
Kanrisuru::Remote::Fstab::Options.new(type, test_opts)
|
130
|
+
else
|
131
|
+
Kanrisuru::Remote::Fstab::Options.new('common', test_opts)
|
132
|
+
end
|
133
|
+
|
134
|
+
command.append_arg('-O', test_options.to_s)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'date'
|
4
|
+
|
5
|
+
module Kanrisuru
|
6
|
+
module Core
|
7
|
+
module Path
|
8
|
+
extend OsPackage::Define
|
9
|
+
|
10
|
+
os_define :linux, :ls
|
11
|
+
os_define :linux, :pwd
|
12
|
+
os_define :linux, :whoami
|
13
|
+
os_define :linux, :which
|
14
|
+
os_define :linux, :realpath
|
15
|
+
os_define :linux, :readlink
|
16
|
+
|
17
|
+
FilePath = Struct.new(:path)
|
18
|
+
FileInfoId = Struct.new(:inode, :mode, :memory_blocks, :uid, :gid, :fsize, :date, :path, :type)
|
19
|
+
FileInfo = Struct.new(:inode, :mode, :memory_blocks, :owner, :group, :fsize, :date, :path, :type)
|
20
|
+
UserName = Struct.new(:user)
|
21
|
+
|
22
|
+
def ls(opts = {})
|
23
|
+
path = opts[:path]
|
24
|
+
all = opts[:all]
|
25
|
+
id = opts[:id]
|
26
|
+
|
27
|
+
command = Kanrisuru::Command.new('ls')
|
28
|
+
command.append_flag('-i')
|
29
|
+
command.append_flag('-l')
|
30
|
+
command.append_flag('-a', all)
|
31
|
+
command.append_flag('-n', id)
|
32
|
+
|
33
|
+
command << (path || pwd.path)
|
34
|
+
execute_shell(command)
|
35
|
+
|
36
|
+
Kanrisuru::Result.new(command) do |cmd|
|
37
|
+
items = []
|
38
|
+
rows = cmd.to_a
|
39
|
+
|
40
|
+
rows.each.with_index do |row, index|
|
41
|
+
next if index.zero?
|
42
|
+
|
43
|
+
values = row.split
|
44
|
+
date = DateTime.parse("#{values[6]} #{values[7]} #{values[8]}")
|
45
|
+
|
46
|
+
type = values[1].include?('d') ? 'directory' : 'file'
|
47
|
+
|
48
|
+
items <<
|
49
|
+
if id
|
50
|
+
FileInfoId.new(
|
51
|
+
values[0].to_i,
|
52
|
+
Kanrisuru::Mode.new(values[1]),
|
53
|
+
values[2].to_i,
|
54
|
+
values[3].to_i,
|
55
|
+
values[4].to_i,
|
56
|
+
values[5].to_i,
|
57
|
+
date,
|
58
|
+
values[9],
|
59
|
+
type
|
60
|
+
)
|
61
|
+
else
|
62
|
+
FileInfo.new(
|
63
|
+
values[0].to_i,
|
64
|
+
Kanrisuru::Mode.new(values[1]),
|
65
|
+
values[2].to_i,
|
66
|
+
values[3],
|
67
|
+
values[4],
|
68
|
+
values[5].to_i,
|
69
|
+
date,
|
70
|
+
values[9],
|
71
|
+
type
|
72
|
+
)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
items
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def whoami
|
81
|
+
command = Kanrisuru::Command.new('whoami')
|
82
|
+
execute_shell(command)
|
83
|
+
|
84
|
+
Kanrisuru::Result.new(command) do |cmd|
|
85
|
+
UserName.new(cmd.to_s)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def pwd
|
90
|
+
command = Kanrisuru::Command.new('pwd')
|
91
|
+
execute_shell(command)
|
92
|
+
|
93
|
+
Kanrisuru::Result.new(command) do |cmd|
|
94
|
+
FilePath.new(cmd.to_s)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def which(program, opts = {})
|
99
|
+
command = Kanrisuru::Command.new('which')
|
100
|
+
command.append_flag('-a', opts[:all])
|
101
|
+
command << program
|
102
|
+
|
103
|
+
execute_shell(command)
|
104
|
+
|
105
|
+
Kanrisuru::Result.new(command) do |cmd|
|
106
|
+
rows = cmd.to_a
|
107
|
+
rows.map do |row|
|
108
|
+
FilePath.new(row)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def realpath(path, opts = {})
|
114
|
+
command = Kanrisuru::Command.new("realpath #{path}")
|
115
|
+
command.append_flag('-s', opts[:strip])
|
116
|
+
|
117
|
+
execute(command)
|
118
|
+
|
119
|
+
Kanrisuru::Result.new(command) do |cmd|
|
120
|
+
FilePath.new(cmd.to_s)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def readlink(path, opts = {})
|
125
|
+
command = Kanrisuru::Command.new('readlink')
|
126
|
+
command.append_flag('-f', opts[:canonicalize])
|
127
|
+
command.append_flag('-e', opts[:canonicalize_existing])
|
128
|
+
command.append_flag('-m', opts[:canonicalize_missing])
|
129
|
+
|
130
|
+
command << path
|
131
|
+
|
132
|
+
execute(command)
|
133
|
+
|
134
|
+
Kanrisuru::Result.new(command) do |cmd|
|
135
|
+
FilePath.new(cmd.to_s)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ipaddr'
|
4
|
+
|
5
|
+
module Kanrisuru
|
6
|
+
module Core
|
7
|
+
module Socket
|
8
|
+
extend OsPackage::Define
|
9
|
+
|
10
|
+
os_define :linux, :ss
|
11
|
+
|
12
|
+
SocketStatistics = Struct.new(
|
13
|
+
:netid, :state, :receive_queue, :send_queue,
|
14
|
+
:local_address, :local_port, :peer_address, :peer_port,
|
15
|
+
:memory
|
16
|
+
)
|
17
|
+
|
18
|
+
SocketStatisticsMemory = Struct.new(
|
19
|
+
:rmem_alloc, :rcv_buf, :wmem_alloc, :snd_buf,
|
20
|
+
:fwd_alloc, :wmem_queued, :ropt_mem, :back_log, :sock_drop
|
21
|
+
)
|
22
|
+
|
23
|
+
TCP_STATES = %w[
|
24
|
+
established syn-sent syn-recv
|
25
|
+
fin-wait-1 fin-wait-2 time-wait
|
26
|
+
closed close-wait last-ack listening closing
|
27
|
+
].freeze
|
28
|
+
|
29
|
+
OTHER_STATES = %w[
|
30
|
+
all connected synchronized bucket syn-recv
|
31
|
+
big
|
32
|
+
].freeze
|
33
|
+
|
34
|
+
TCP_STATE_ABBR = {
|
35
|
+
'ESTAB' => 'established', 'LISTEN' => 'listening', 'UNCONN' => 'unconnected',
|
36
|
+
'SYN-SENT' => 'syn-sent', 'SYN-RECV' => 'syn-recv', 'FIN-WAIT-1' => 'fin-wait-1',
|
37
|
+
'FIN-WAIT-2' => 'fin-wait-2', 'TIME-WAIT' => 'time-wait', 'CLOSE-WAIT' => 'close-wait',
|
38
|
+
'LAST-ACK' => 'last-ack', 'CLOSING' => 'closing'
|
39
|
+
}.freeze
|
40
|
+
|
41
|
+
def ss(opts = {})
|
42
|
+
state = opts[:state]
|
43
|
+
expression = opts[:expression]
|
44
|
+
|
45
|
+
command = Kanrisuru::Command.new('ss')
|
46
|
+
|
47
|
+
command.append_flag('-a')
|
48
|
+
command.append_flag('-m')
|
49
|
+
|
50
|
+
command.append_flag('-n', opts[:numeric])
|
51
|
+
command.append_flag('-t', opts[:tcp])
|
52
|
+
command.append_flag('-u', opts[:udp])
|
53
|
+
command.append_flag('-x', opts[:unix])
|
54
|
+
command.append_flag('-w', opts[:raw])
|
55
|
+
|
56
|
+
command.append_arg('-f', opts[:family])
|
57
|
+
|
58
|
+
if Kanrisuru::Util.present?(state)
|
59
|
+
raise ArgumentError, 'invalid filter state' if !TCP_STATES.include?(state) && !OTHER_STATES.include?(state)
|
60
|
+
|
61
|
+
command.append_arg('state', state)
|
62
|
+
end
|
63
|
+
|
64
|
+
command << expression if Kanrisuru::Util.present?(expression)
|
65
|
+
|
66
|
+
execute_shell(command)
|
67
|
+
|
68
|
+
Kanrisuru::Result.new(command) do |cmd|
|
69
|
+
rows = []
|
70
|
+
|
71
|
+
## New lines with tabs are from text overflow
|
72
|
+
## on on stdout of SS command.
|
73
|
+
## Replace the newline and tab chars with a space.
|
74
|
+
string = cmd.raw_result.join
|
75
|
+
string = string.gsub("\n\t", "\s")
|
76
|
+
lines = string.lines.map(&:strip)
|
77
|
+
|
78
|
+
headers = lines.shift
|
79
|
+
|
80
|
+
lines.each do |line|
|
81
|
+
values = line.split
|
82
|
+
next if values.length < 5
|
83
|
+
|
84
|
+
socket_stats = SocketStatistics.new
|
85
|
+
|
86
|
+
socket_stats.netid = if headers.include?('Netid')
|
87
|
+
values.shift
|
88
|
+
elsif opts[:tcp]
|
89
|
+
'tcp'
|
90
|
+
elsif opts[:udp]
|
91
|
+
'udp'
|
92
|
+
elsif opts[:raw]
|
93
|
+
'raw'
|
94
|
+
else
|
95
|
+
''
|
96
|
+
end
|
97
|
+
|
98
|
+
socket_stats.state = if headers.include?('State')
|
99
|
+
TCP_STATE_ABBR[values.shift]
|
100
|
+
else
|
101
|
+
state
|
102
|
+
end
|
103
|
+
|
104
|
+
socket_stats.receive_queue = values.shift.to_i
|
105
|
+
socket_stats.send_queue = values.shift.to_i
|
106
|
+
|
107
|
+
address, port = parse_address_port(values)
|
108
|
+
socket_stats.local_address = address
|
109
|
+
socket_stats.local_port = port
|
110
|
+
|
111
|
+
address, port = parse_address_port(values)
|
112
|
+
socket_stats.peer_address = address
|
113
|
+
socket_stats.peer_port = port
|
114
|
+
|
115
|
+
socket_stats.memory = parse_memory(values.shift)
|
116
|
+
|
117
|
+
rows << socket_stats
|
118
|
+
end
|
119
|
+
|
120
|
+
rows
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
private
|
125
|
+
|
126
|
+
def parse_memory(string)
|
127
|
+
return if Kanrisuru::Util.blank?(string) ||
|
128
|
+
Regexp.new(/skmem:\((\S+)\)/).match(string).nil?
|
129
|
+
|
130
|
+
_, string = string.split(/skmem:\((\S+)\)/)
|
131
|
+
values = string.split(',')
|
132
|
+
|
133
|
+
memory = SocketStatisticsMemory.new
|
134
|
+
memory.rmem_alloc = values[0].split(/(\d+)/)[1].to_i
|
135
|
+
memory.rcv_buf = values[1].split(/(\d+)/)[1].to_i
|
136
|
+
memory.wmem_alloc = values[2].split(/(\d+)/)[1].to_i
|
137
|
+
memory.snd_buf = values[3].split(/(\d+)/)[1].to_i
|
138
|
+
memory.fwd_alloc = values[4].split(/(\d+)/)[1].to_i
|
139
|
+
memory.wmem_queued = values[5].split(/(\d+)/)[1].to_i
|
140
|
+
memory.ropt_mem = values[6].split(/(\d+)/)[1].to_i
|
141
|
+
memory.back_log = values[7].split(/(\d+)/)[1].to_i
|
142
|
+
memory.sock_drop = values[8].split(/(\d+)/)[1].to_i
|
143
|
+
|
144
|
+
memory
|
145
|
+
end
|
146
|
+
|
147
|
+
def parse_address_port(values)
|
148
|
+
address = values.shift
|
149
|
+
port = nil
|
150
|
+
|
151
|
+
if address == '*' && Regexp.new(/skmem:\((\S+)\)/).match(values[0])
|
152
|
+
port = '*'
|
153
|
+
elsif Regexp.new(/\[(\S+)\]/).match(address)
|
154
|
+
tokens = address.split(/\[(\S+)\]/)
|
155
|
+
address = "[#{tokens[1]}]"
|
156
|
+
_, port = tokens[2].split(/:(\S+)/)
|
157
|
+
elsif Regexp.new(/:\S+/).match(address)
|
158
|
+
address, port = address.split(/:(\S+)/)
|
159
|
+
else
|
160
|
+
port = values.shift
|
161
|
+
end
|
162
|
+
|
163
|
+
port = Kanrisuru::Util.numeric?(port) ? port.to_i : port
|
164
|
+
[address, port]
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'date'
|
4
|
+
|
5
|
+
module Kanrisuru
|
6
|
+
module Core
|
7
|
+
module Stat
|
8
|
+
extend OsPackage::Define
|
9
|
+
|
10
|
+
os_define :linux, :dir?
|
11
|
+
os_define :linux, :file?
|
12
|
+
os_define :linux, :block_device?
|
13
|
+
os_define :linux, :char_device?
|
14
|
+
os_define :linux, :symlink?
|
15
|
+
os_define :linux, :file_type?
|
16
|
+
os_define :linux, :inode?
|
17
|
+
os_define :linux, :stat
|
18
|
+
|
19
|
+
FileStat = Struct.new(
|
20
|
+
:mode, :blocks, :device, :file_type,
|
21
|
+
:gid, :group, :links, :inode,
|
22
|
+
:path, :fsize, :uid, :user,
|
23
|
+
:last_access, :last_modified, :last_changed
|
24
|
+
)
|
25
|
+
|
26
|
+
def dir?(path)
|
27
|
+
file_type?(path, 'directory')
|
28
|
+
end
|
29
|
+
|
30
|
+
def file?(path)
|
31
|
+
file_type?(path, 'regular file')
|
32
|
+
end
|
33
|
+
|
34
|
+
def empty_file?(path)
|
35
|
+
file_type?(path, 'regular empty file')
|
36
|
+
end
|
37
|
+
|
38
|
+
def block_device?(path)
|
39
|
+
file_type?(path, 'block special file')
|
40
|
+
end
|
41
|
+
|
42
|
+
def char_device?(path)
|
43
|
+
file_type?(path, 'character special file')
|
44
|
+
end
|
45
|
+
|
46
|
+
def symlink?(path)
|
47
|
+
file_type?(path, 'symbolic link')
|
48
|
+
end
|
49
|
+
|
50
|
+
def inode?(path)
|
51
|
+
command = Kanrisuru::Command.new("stat #{path}")
|
52
|
+
command.append_arg('-c', '%i')
|
53
|
+
|
54
|
+
execute_shell(command)
|
55
|
+
command.success?
|
56
|
+
end
|
57
|
+
|
58
|
+
def file_type?(path, type)
|
59
|
+
command = Kanrisuru::Command.new("stat #{path}")
|
60
|
+
command.append_arg('-c', '%F')
|
61
|
+
|
62
|
+
execute(command)
|
63
|
+
|
64
|
+
result = Kanrisuru::Result.new(command, &:to_s)
|
65
|
+
|
66
|
+
result.success? ? result.data == type : false
|
67
|
+
end
|
68
|
+
|
69
|
+
def stat(path, opts = {})
|
70
|
+
follow = opts[:follow]
|
71
|
+
|
72
|
+
command = Kanrisuru::Command.new('stat')
|
73
|
+
command.append_flag('-L', follow)
|
74
|
+
command.append_arg('-c', '%A,%b,%D,%F,%g,%G,%h,%i,%n,%s,%u,%U,%x,%y,%z')
|
75
|
+
command << path
|
76
|
+
|
77
|
+
execute(command)
|
78
|
+
|
79
|
+
Kanrisuru::Result.new(command) do |cmd|
|
80
|
+
string = cmd.to_s
|
81
|
+
values = string.split(',')
|
82
|
+
|
83
|
+
FileStat.new(
|
84
|
+
Kanrisuru::Mode.new(values[0]),
|
85
|
+
values[1].to_i,
|
86
|
+
values[2],
|
87
|
+
values[3],
|
88
|
+
values[4].to_i,
|
89
|
+
values[5],
|
90
|
+
values[6].to_i,
|
91
|
+
values[7].to_i,
|
92
|
+
values[8],
|
93
|
+
values[9].to_i,
|
94
|
+
values[10].to_i,
|
95
|
+
values[11],
|
96
|
+
values[12] ? DateTime.parse(values[12]) : nil,
|
97
|
+
values[13] ? DateTime.parse(values[13]) : nil,
|
98
|
+
values[14] ? DateTime.parse(values[14]) : nil
|
99
|
+
)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|