kanrisuru 0.10.0 → 0.12.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.
- checksums.yaml +4 -4
- data/.github/CONTRIBUTING.md +9 -9
- data/.github/ISSUE_TEMPLATE/bug_report.md +7 -8
- data/.rspec +1 -1
- data/CHANGELOG.md +127 -102
- data/CODE_OF_CONDUCT.md +10 -10
- data/README.md +19 -90
- data/kanrisuru.gemspec +2 -1
- data/lib/kanrisuru/command.rb +7 -0
- data/lib/kanrisuru/core/archive.rb +11 -35
- data/lib/kanrisuru/core/disk.rb +0 -3
- data/lib/kanrisuru/core/dmi.rb +1 -1
- data/lib/kanrisuru/core/file.rb +4 -11
- data/lib/kanrisuru/core/find.rb +6 -11
- data/lib/kanrisuru/core/mount.rb +14 -15
- data/lib/kanrisuru/core/socket.rb +2 -1
- data/lib/kanrisuru/core/stream.rb +1 -2
- data/lib/kanrisuru/core/zypper.rb +6 -23
- data/lib/kanrisuru/os_package/collection.rb +58 -0
- data/lib/kanrisuru/os_package/define.rb +34 -0
- data/lib/kanrisuru/os_package/include.rb +163 -0
- data/lib/kanrisuru/os_package.rb +3 -245
- data/lib/kanrisuru/remote/cpu.rb +5 -1
- data/lib/kanrisuru/remote/fstab.rb +5 -5
- data/lib/kanrisuru/result.rb +5 -4
- data/lib/kanrisuru/util.rb +1 -1
- data/lib/kanrisuru/version.rb +1 -1
- data/spec/functional/core/apt_spec.rb +22 -30
- data/spec/functional/core/archive_spec.rb +96 -120
- data/spec/functional/core/find_spec.rb +94 -113
- data/spec/functional/core/mount_spec.rb +121 -0
- data/spec/functional/core/socket_spec.rb +23 -28
- data/spec/functional/core/stream_spec.rb +12 -12
- data/spec/functional/core/transfer_spec.rb +108 -131
- data/spec/functional/core/yum_spec.rb +58 -83
- data/spec/functional/remote/cluster_spec.rb +11 -2
- data/spec/functional/remote/cpu_spec.rb +104 -0
- data/spec/functional/remote/env_spec.rb +3 -5
- data/spec/helper/stub_network.rb +35 -16
- data/spec/helper/test_hosts.rb +11 -1
- data/spec/integration/core/apt_spec.rb +2 -3
- data/spec/integration/core/archive_spec.rb +8 -13
- data/spec/integration/core/disk_spec.rb +2 -3
- data/spec/integration/core/dmi_spec.rb +2 -3
- data/spec/integration/core/file_spec.rb +4 -14
- data/spec/integration/core/find_spec.rb +3 -3
- data/spec/integration/core/group_spec.rb +2 -3
- data/spec/integration/core/ip_spec.rb +2 -3
- data/spec/integration/core/path_spec.rb +2 -3
- data/spec/integration/core/socket_spec.rb +2 -4
- data/spec/integration/core/stat_spec.rb +2 -3
- data/spec/integration/core/stream_spec.rb +6 -9
- data/spec/integration/core/system_spec.rb +2 -4
- data/spec/integration/core/transfer_spec.rb +4 -9
- data/spec/integration/core/user_spec.rb +2 -4
- data/spec/integration/core/yum_spec.rb +2 -3
- data/spec/integration/core/zypper_spec.rb +5 -6
- data/spec/integration/remote/cpu_spec.rb +2 -3
- data/spec/integration/remote/env_spec.rb +2 -3
- data/spec/integration/remote/fstab_spec.rb +2 -3
- data/spec/integration/remote/host_spec.rb +2 -3
- data/spec/integration/remote/memory_spec.rb +2 -2
- data/spec/integration/remote/os_spec.rb +2 -3
- data/spec/integration/remote/remote_file_spec.rb +9 -15
- data/spec/spec_helper.rb +12 -3
- data/spec/unit/command_spec.rb +19 -1
- data/spec/unit/core/find_spec.rb +1 -1
- data/spec/unit/core/yum_spec.rb +1 -1
- data/spec/unit/mode_spec.rb +2 -2
- data/spec/unit/remote/cluster_spec.rb +3 -1
- data/spec/unit/remote/cpu_spec.rb +1 -2
- data/spec/unit/remote/env_spec.rb +1 -3
- data/spec/unit/util_spec.rb +13 -0
- metadata +23 -4
data/lib/kanrisuru/command.rb
CHANGED
@@ -84,6 +84,13 @@ module Kanrisuru
|
|
84
84
|
append_value("| #{value}")
|
85
85
|
end
|
86
86
|
|
87
|
+
def append_array(value)
|
88
|
+
return unless Kanrisuru::Util.present?(value)
|
89
|
+
|
90
|
+
value = [value] if value.instance_of?(String)
|
91
|
+
append_value(value.join(' '))
|
92
|
+
end
|
93
|
+
|
87
94
|
def append_value(value)
|
88
95
|
@raw_command = "#{@raw_command} #{value}"
|
89
96
|
end
|
@@ -10,18 +10,16 @@ module Kanrisuru
|
|
10
10
|
FilePath = Struct.new(:path)
|
11
11
|
|
12
12
|
def tar(action, file, opts = {})
|
13
|
-
compress = opts[:compress]
|
14
13
|
paths = opts[:paths]
|
15
14
|
exclude = opts[:exclude]
|
16
|
-
directory = opts[:directory]
|
17
15
|
|
18
16
|
command = Kanrisuru::Command.new('tar --restrict')
|
19
17
|
|
20
|
-
directory = realpath(directory, strip: true).path
|
18
|
+
directory = opts[:directory] ? realpath(opts[:directory], strip: true).path : nil
|
21
19
|
command.append_arg('-C', directory)
|
22
20
|
command.append_arg('-f', file)
|
23
21
|
|
24
|
-
set_compression(command, compress) if compress
|
22
|
+
set_compression(command, opts[:compress]) if opts[:compress]
|
25
23
|
|
26
24
|
case action
|
27
25
|
when 'list', 't'
|
@@ -58,10 +56,7 @@ module Kanrisuru
|
|
58
56
|
command.append_flag('--unlink-first', opts[:unlink_first])
|
59
57
|
command.append_flag('--recursive-unlink', opts[:recursive_unlink])
|
60
58
|
|
61
|
-
|
62
|
-
paths = paths.instance_of?(String) ? [paths] : paths
|
63
|
-
command << paths.join(' ')
|
64
|
-
end
|
59
|
+
command.append_array(paths)
|
65
60
|
|
66
61
|
execute_shell(command)
|
67
62
|
Kanrisuru::Result.new(command)
|
@@ -70,46 +65,31 @@ module Kanrisuru
|
|
70
65
|
command.append_flag('--multi-volume', opts[:multi_volume])
|
71
66
|
|
72
67
|
if Kanrisuru::Util.present?(exclude)
|
73
|
-
|
74
|
-
|
75
|
-
command << "--exclude=#{
|
68
|
+
options = exclude.instance_of?(String) ? [exclude] : exclude
|
69
|
+
options.each do |option|
|
70
|
+
command << "--exclude=#{option}"
|
76
71
|
end
|
77
72
|
end
|
78
73
|
|
79
|
-
|
80
|
-
paths = paths.instance_of?(String) ? [paths] : paths
|
81
|
-
command << paths.join(' ')
|
82
|
-
end
|
74
|
+
command.append_array(paths)
|
83
75
|
|
84
76
|
execute_shell(command)
|
85
77
|
Kanrisuru::Result.new(command)
|
86
78
|
when 'append', 'r'
|
87
79
|
command.append_flag('-r')
|
88
|
-
|
89
|
-
if Kanrisuru::Util.present?(paths)
|
90
|
-
paths = paths.instance_of?(String) ? [paths] : paths
|
91
|
-
command << paths.join(' ')
|
92
|
-
end
|
80
|
+
command.append_array(paths)
|
93
81
|
|
94
82
|
execute_shell(command)
|
95
83
|
Kanrisuru::Result.new(command)
|
96
84
|
when 'catenate', 'concat', 'A'
|
97
85
|
command.append_flag('-A')
|
98
|
-
|
99
|
-
if Kanrisuru::Util.present?(paths)
|
100
|
-
paths = paths.instance_of?(String) ? [paths] : paths
|
101
|
-
command << paths.join(' ')
|
102
|
-
end
|
86
|
+
command.append_array(paths)
|
103
87
|
|
104
88
|
execute_shell(command)
|
105
89
|
Kanrisuru::Result.new(command)
|
106
90
|
when 'update', 'u'
|
107
91
|
command.append_flag('-u')
|
108
|
-
|
109
|
-
if Kanrisuru::Util.present?(paths)
|
110
|
-
paths = paths.instance_of?(String) ? [paths] : paths
|
111
|
-
command << paths.join(' ')
|
112
|
-
end
|
92
|
+
command.append_array(paths)
|
113
93
|
|
114
94
|
execute_shell(command)
|
115
95
|
Kanrisuru::Result.new(command)
|
@@ -122,11 +102,7 @@ module Kanrisuru
|
|
122
102
|
when 'delete'
|
123
103
|
command.append_flag('--delete')
|
124
104
|
command.append_arg('--occurrence', opts[:occurrence])
|
125
|
-
|
126
|
-
if Kanrisuru::Util.present?(paths)
|
127
|
-
paths = paths.instance_of?(String) ? [paths] : paths
|
128
|
-
command << paths.join(' ')
|
129
|
-
end
|
105
|
+
command.append_array(paths)
|
130
106
|
|
131
107
|
execute_shell(command)
|
132
108
|
Kanrisuru::Result.new(command)
|
data/lib/kanrisuru/core/disk.rb
CHANGED
data/lib/kanrisuru/core/dmi.rb
CHANGED
@@ -511,7 +511,7 @@ module Kanrisuru
|
|
511
511
|
return unless Kanrisuru::Util.present?(opts[:types])
|
512
512
|
|
513
513
|
types = opts[:types]
|
514
|
-
types = types.instance_of?(
|
514
|
+
types = [types] if types.instance_of?(String)
|
515
515
|
|
516
516
|
types.each do |type|
|
517
517
|
type = parse_dmi_type(type)
|
data/lib/kanrisuru/core/file.rb
CHANGED
@@ -64,12 +64,9 @@ module Kanrisuru
|
|
64
64
|
command << dest
|
65
65
|
elsif opts[:target_directory]
|
66
66
|
command.append_arg('-t', dest)
|
67
|
-
|
68
|
-
source = source.instance_of?(String) ? [source] : source
|
69
|
-
command << source.join(' ')
|
67
|
+
command.append_array(source)
|
70
68
|
else
|
71
|
-
|
72
|
-
command << source.join(' ')
|
69
|
+
command.append_array(source)
|
73
70
|
command << dest
|
74
71
|
end
|
75
72
|
|
@@ -108,13 +105,9 @@ module Kanrisuru
|
|
108
105
|
command << dest
|
109
106
|
elsif opts[:target_directory]
|
110
107
|
command.append_arg('-t', dest)
|
111
|
-
|
112
|
-
source = source.instance_of?(String) ? [source] : source
|
113
|
-
command << source.join(' ')
|
108
|
+
command.append_array(source)
|
114
109
|
else
|
115
|
-
|
116
|
-
|
117
|
-
command << source.join(' ')
|
110
|
+
command.append_array(source)
|
118
111
|
command << dest
|
119
112
|
end
|
120
113
|
|
data/lib/kanrisuru/core/find.rb
CHANGED
@@ -10,7 +10,7 @@ module Kanrisuru
|
|
10
10
|
os_define :linux, :find
|
11
11
|
|
12
12
|
FilePath = Struct.new(:path)
|
13
|
-
REGEX_TYPES = [
|
13
|
+
REGEX_TYPES = %w[emacs posix-awk posix-basic posix-egrep posix-extended].freeze
|
14
14
|
|
15
15
|
def find(opts = {})
|
16
16
|
paths = opts[:paths]
|
@@ -30,13 +30,9 @@ module Kanrisuru
|
|
30
30
|
end
|
31
31
|
|
32
32
|
if Kanrisuru::Util.present?(paths)
|
33
|
-
|
34
|
-
paths = paths.join(' ')
|
35
|
-
elsif paths.class != String
|
36
|
-
raise ArgumentError, 'Invalid paths type'
|
37
|
-
end
|
33
|
+
raise ArgumentError, 'Invalid paths type' unless [String, Array].include?(paths.class)
|
38
34
|
|
39
|
-
command
|
35
|
+
command.append_array(paths)
|
40
36
|
end
|
41
37
|
|
42
38
|
command.append_flag('-executable', opts[:executable])
|
@@ -66,9 +62,7 @@ module Kanrisuru
|
|
66
62
|
command.append_arg('-mmin', opts[:mmin])
|
67
63
|
|
68
64
|
if Kanrisuru::Util.present?(opts[:regex_type])
|
69
|
-
unless REGEX_TYPES.include?(opts[:regex_type])
|
70
|
-
raise ArgumentError, 'invalid regex type'
|
71
|
-
end
|
65
|
+
raise ArgumentError, 'invalid regex type' unless REGEX_TYPES.include?(opts[:regex_type])
|
72
66
|
|
73
67
|
command.append_arg('-regextype', opts[:regex_type])
|
74
68
|
end
|
@@ -77,7 +71,8 @@ module Kanrisuru
|
|
77
71
|
|
78
72
|
if size.instance_of?(String)
|
79
73
|
regex = Regexp.new(/^([-+])?(\d+)([bcwkMG])*$/)
|
80
|
-
raise ArgumentError, "invalid size string: '#{@size}'" unless regex.match?(size)
|
74
|
+
raise ArgumentError, "invalid size string: '#{@size}'" unless regex.match?(size)
|
75
|
+
|
81
76
|
command.append_arg('-size', size)
|
82
77
|
elsif size.instance_of?(Integer)
|
83
78
|
command.append_arg('-size', size)
|
data/lib/kanrisuru/core/mount.rb
CHANGED
@@ -10,9 +10,6 @@ module Kanrisuru
|
|
10
10
|
|
11
11
|
def mount(opts = {})
|
12
12
|
type = opts[:type]
|
13
|
-
all = opts[:all]
|
14
|
-
device = opts[:device]
|
15
|
-
directory = opts[:directory]
|
16
13
|
|
17
14
|
bind_old = opts[:bind_old]
|
18
15
|
bind_new = opts[:bind_new]
|
@@ -39,13 +36,12 @@ module Kanrisuru
|
|
39
36
|
else
|
40
37
|
command.append_arg('-L', opts[:label])
|
41
38
|
command.append_arg('-U', opts[:uuid])
|
42
|
-
command.append_flag('-n', opts[:no_mtab])
|
43
39
|
command.append_flag('-f', opts[:fake])
|
44
40
|
command.append_flag('-i', opts[:internal_only])
|
45
41
|
command.append_flag('-s', opts[:sloppy])
|
46
42
|
|
47
43
|
command.append_flag('--no-mtab', opts[:no_mtab])
|
48
|
-
command.append_flag('--no-
|
44
|
+
command.append_flag('--no-canonicalize', opts[:no_canonicalize])
|
49
45
|
|
50
46
|
fs_options = nil
|
51
47
|
if Kanrisuru::Util.present?(type)
|
@@ -55,14 +51,14 @@ module Kanrisuru
|
|
55
51
|
fs_options = Kanrisuru::Remote::Fstab::Options.new('common', fs_opts)
|
56
52
|
end
|
57
53
|
|
58
|
-
if Kanrisuru::Util.present?(all)
|
54
|
+
if Kanrisuru::Util.present?(opts[:all])
|
59
55
|
command.append_flag('-a')
|
60
56
|
add_test_opts(command, opts[:test_opts], type)
|
61
57
|
else
|
62
58
|
command.append_arg('-o', fs_options.to_s)
|
63
59
|
|
64
|
-
command << device if Kanrisuru::Util.present?(device)
|
65
|
-
command << directory if Kanrisuru::Util.present?(directory)
|
60
|
+
command << opts[:device] if Kanrisuru::Util.present?(opts[:device])
|
61
|
+
command << opts[:directory] if Kanrisuru::Util.present?(opts[:directory])
|
66
62
|
end
|
67
63
|
end
|
68
64
|
|
@@ -75,12 +71,6 @@ module Kanrisuru
|
|
75
71
|
type = opts[:type]
|
76
72
|
command = Kanrisuru::Command.new('umount')
|
77
73
|
|
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
74
|
command.append_flag('--fake', opts[:fake])
|
85
75
|
command.append_flag('--no-canonicalize', opts[:no_canonicalize])
|
86
76
|
command.append_flag('-n', opts[:no_mtab])
|
@@ -90,6 +80,15 @@ module Kanrisuru
|
|
90
80
|
command.append_flag('-l', opts[:lazy])
|
91
81
|
command.append_flag('-f', opts[:force])
|
92
82
|
|
83
|
+
if Kanrisuru::Util.present?(all)
|
84
|
+
command.append_flag('-a')
|
85
|
+
add_type(command, type)
|
86
|
+
add_test_opts(command, opts[:test_opts], type)
|
87
|
+
else
|
88
|
+
command << opts[:device] if Kanrisuru::Util.present?(opts[:device])
|
89
|
+
command << opts[:directory] if Kanrisuru::Util.present?(opts[:directory])
|
90
|
+
end
|
91
|
+
|
93
92
|
execute_shell(command)
|
94
93
|
|
95
94
|
Kanrisuru::Result.new(command)
|
@@ -115,7 +114,7 @@ module Kanrisuru
|
|
115
114
|
|
116
115
|
test_types.each do |t|
|
117
116
|
device_opts = Kanrisuru::Util::FsMountOpts.get_device(t)
|
118
|
-
raise
|
117
|
+
raise ArgumentError, "Invalid fstype: #{t}" unless device_opts
|
119
118
|
end
|
120
119
|
|
121
120
|
command.append_arg('-t', type)
|
@@ -59,7 +59,8 @@ module Kanrisuru
|
|
59
59
|
command.append_flag('-w', opts[:raw])
|
60
60
|
|
61
61
|
if Kanrisuru::Util.present?(family)
|
62
|
-
raise ArgumentError, 'invalid family type'
|
62
|
+
raise ArgumentError, 'invalid family type' unless NETWORK_FAMILIES.include?(family)
|
63
|
+
|
63
64
|
command.append_arg('-f', family)
|
64
65
|
end
|
65
66
|
|
@@ -95,8 +95,7 @@ module Kanrisuru
|
|
95
95
|
command.append_flag('-b', opts[:number_nonblank])
|
96
96
|
command.append_flag('-A', opts[:show_all])
|
97
97
|
|
98
|
-
|
99
|
-
command << files.join(' ')
|
98
|
+
command.append_array(files)
|
100
99
|
|
101
100
|
append_file(command, opts)
|
102
101
|
execute_shell(command)
|
@@ -181,8 +181,7 @@ module Kanrisuru
|
|
181
181
|
command.append_flag('--metadata', opts[:metadata])
|
182
182
|
command.append_flag('--raw-metadata', opts[:raw_metadata])
|
183
183
|
command.append_flag('--all', opts[:all])
|
184
|
-
|
185
|
-
command << opts[:repos]
|
184
|
+
command.append_array(opts[:repos])
|
186
185
|
|
187
186
|
execute_shell(command)
|
188
187
|
|
@@ -276,11 +275,7 @@ module Kanrisuru
|
|
276
275
|
command.append_arg('--medium-type', opts[:medium_type])
|
277
276
|
end
|
278
277
|
|
279
|
-
|
280
|
-
if Kanrisuru::Util.present?(repos)
|
281
|
-
repos = repos.instance_of?(String) ? [repos] : repos
|
282
|
-
command << repos.join(' ')
|
283
|
-
end
|
278
|
+
command.append_array(opts[:repos])
|
284
279
|
|
285
280
|
execute_shell(command)
|
286
281
|
|
@@ -336,11 +331,7 @@ module Kanrisuru
|
|
336
331
|
command.append_arg('--media-type', opts[:media_type])
|
337
332
|
end
|
338
333
|
|
339
|
-
|
340
|
-
if Kanrisuru::Util.present?(repos)
|
341
|
-
repos = repos.instance_of?(String) ? [repos] : repos
|
342
|
-
command << repos.join(' ')
|
343
|
-
end
|
334
|
+
command.append_array(opts[:repos])
|
344
335
|
|
345
336
|
execute_shell(command)
|
346
337
|
|
@@ -372,11 +363,7 @@ module Kanrisuru
|
|
372
363
|
command.append_flag('--refresh', opts[:refresh])
|
373
364
|
command.append_flag('--no-refresh', opts[:no_refresh])
|
374
365
|
|
375
|
-
|
376
|
-
if Kanrisuru::Util.present?(services)
|
377
|
-
services = services.instance_of?(Array) ? services : [services]
|
378
|
-
command << services.join(' ')
|
379
|
-
end
|
366
|
+
command.append_array(opts[:services])
|
380
367
|
|
381
368
|
execute_shell(command)
|
382
369
|
|
@@ -386,15 +373,11 @@ module Kanrisuru
|
|
386
373
|
def zypper_remove_service(opts)
|
387
374
|
command = Kanrisuru::Command.new('zypper')
|
388
375
|
zypper_global_opts(command, opts)
|
376
|
+
|
389
377
|
command << 'removeservice'
|
390
378
|
command.append_flag('--loose-auth', opts[:loose_auth])
|
391
379
|
command.append_flag('--loose-query', opts[:loose_query])
|
392
|
-
|
393
|
-
services = opts[:services]
|
394
|
-
if Kanrisuru::Util.present?(services)
|
395
|
-
services = services.instance_of?(String) ? [services] : services
|
396
|
-
command << services.join(' ')
|
397
|
-
end
|
380
|
+
command.append_array(opts[:services])
|
398
381
|
|
399
382
|
execute_shell(command)
|
400
383
|
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kanrisuru
|
4
|
+
module OsPackage
|
5
|
+
module Collection
|
6
|
+
def os_collection(mod, opts = {})
|
7
|
+
os_method_properties = mod.instance_variable_get(:@os_method_properties)
|
8
|
+
os_method_names = os_method_properties.keys
|
9
|
+
|
10
|
+
namespace = opts[:namespace]
|
11
|
+
namespace_instance = nil
|
12
|
+
|
13
|
+
if namespace
|
14
|
+
## Define the namespace as an eigen class instance on the host.
|
15
|
+
## Namespaced instances will access core host methods
|
16
|
+
## with @host instance variable.
|
17
|
+
|
18
|
+
if Kanrisuru::Remote::Cluster.instance_variable_defined?("@#{namespace}")
|
19
|
+
namespace_class = Kanrisuru::Remote::Cluster.const_get(Kanrisuru::Util.camelize(namespace))
|
20
|
+
namespace_instance = instance_variable_get("@#{namespace}")
|
21
|
+
else
|
22
|
+
namespace_class = Kanrisuru::Remote::Cluster.const_set(Kanrisuru::Util.camelize(namespace), Class.new)
|
23
|
+
namespace_instance = Kanrisuru::Remote::Cluster.instance_variable_set("@#{namespace}", namespace_class.new)
|
24
|
+
|
25
|
+
class_eval do
|
26
|
+
define_method namespace do
|
27
|
+
namespace_instance.instance_variable_set(:@cluster, self)
|
28
|
+
namespace_instance
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
namespace_class.class_eval do
|
34
|
+
os_method_names.each do |method_name|
|
35
|
+
define_method method_name do |*args, &block|
|
36
|
+
cluster = namespace_instance.instance_variable_get(:@cluster)
|
37
|
+
hosts = cluster.instance_variable_get(:@hosts)
|
38
|
+
hosts.map do |host_addr, host|
|
39
|
+
{ host: host_addr, result: host.send(namespace).send(method_name, *args, &block) }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
else
|
45
|
+
class_eval do
|
46
|
+
os_method_names.each do |method_name|
|
47
|
+
define_method method_name do |*args, &block|
|
48
|
+
@hosts.map do |host_addr, host|
|
49
|
+
{ host: host_addr, result: host.send(method_name, *args, &block) }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kanrisuru
|
4
|
+
module OsPackage
|
5
|
+
module Define
|
6
|
+
def self.extended(base)
|
7
|
+
base.instance_variable_set(:@os_method_properties, {})
|
8
|
+
base.instance_variable_set(:@os_methods, Set.new)
|
9
|
+
end
|
10
|
+
|
11
|
+
def os_define(os_name, method_name, options = {})
|
12
|
+
unique_method_name = options[:alias] || method_name
|
13
|
+
|
14
|
+
@os_methods.add(method_name)
|
15
|
+
|
16
|
+
if @os_method_properties.key?(unique_method_name)
|
17
|
+
params = {
|
18
|
+
os_name: os_name.to_s,
|
19
|
+
method_name: method_name,
|
20
|
+
options: options
|
21
|
+
}
|
22
|
+
|
23
|
+
@os_method_properties[unique_method_name].prepend(params)
|
24
|
+
else
|
25
|
+
@os_method_properties[unique_method_name] = [{
|
26
|
+
os_name: os_name.to_s,
|
27
|
+
method_name: method_name,
|
28
|
+
options: options
|
29
|
+
}]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,163 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kanrisuru
|
4
|
+
module OsPackage
|
5
|
+
module Include
|
6
|
+
def os_include(mod, opts = {})
|
7
|
+
os_method_properties = mod.instance_variable_get(:@os_method_properties)
|
8
|
+
os_method_names = os_method_properties.keys
|
9
|
+
|
10
|
+
## Need to encapsulate any helper methods called in the module
|
11
|
+
## to bind to the host instance. This acts as a psudeo module include.
|
12
|
+
os_methods = mod.instance_variable_get(:@os_methods)
|
13
|
+
|
14
|
+
public_methods = mod.instance_methods(false) - os_methods.to_a
|
15
|
+
private_methods = mod.private_instance_methods(false)
|
16
|
+
protected_methods = mod.protected_instance_methods(false)
|
17
|
+
include_methods = (public_methods + protected_methods + private_methods).flatten
|
18
|
+
|
19
|
+
include_method_bindings = proc do
|
20
|
+
include_methods.each do |method_name|
|
21
|
+
define_method method_name do |*args, &block|
|
22
|
+
unbound_method = mod.instance_method(method_name)
|
23
|
+
bind_method(unbound_method, *args, &block)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private_methods.each { |method_name| private(method_name) }
|
28
|
+
protected_methods.each { |method_name| protected(method_name) }
|
29
|
+
|
30
|
+
private
|
31
|
+
if RUBY_VERSION < '2.7'
|
32
|
+
define_method 'bind_method' do |unbound_method, *args, &block|
|
33
|
+
unbound_method.bind(self).call(*args, &block)
|
34
|
+
end
|
35
|
+
else
|
36
|
+
define_method 'bind_method' do |unbound_method, *args, &block|
|
37
|
+
unbound_method.bind_call(self, *args, &block)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
namespace = opts[:namespace]
|
43
|
+
namespace_class = nil
|
44
|
+
namespace_instance = nil
|
45
|
+
|
46
|
+
if namespace
|
47
|
+
## Define the namespace as an eigen class instance within the host class.
|
48
|
+
## Namespaced instances will access core host methods
|
49
|
+
## with @host instance variable.
|
50
|
+
|
51
|
+
## Check to see if the namespace was defined. If so, additional methods will be appended to the
|
52
|
+
## existing namespace class definition, otherwise, a new namespace class and instance will be
|
53
|
+
## defined with the methods added.
|
54
|
+
if Kanrisuru::Remote::Host.instance_variable_defined?("@#{namespace}")
|
55
|
+
namespace_class = Kanrisuru::Remote::Host.const_get(Kanrisuru::Util.camelize(namespace))
|
56
|
+
namespace_instance = Kanrisuru::Remote::Host.instance_variable_get("@#{namespace}")
|
57
|
+
else
|
58
|
+
namespace_class = Kanrisuru::Remote::Host.const_set(Kanrisuru::Util.camelize(namespace), Class.new)
|
59
|
+
namespace_instance = Kanrisuru::Remote::Host.instance_variable_set("@#{namespace}", namespace_class.new)
|
60
|
+
|
61
|
+
class_eval do
|
62
|
+
define_method namespace do
|
63
|
+
namespace_instance.instance_variable_set(:@host, self)
|
64
|
+
namespace_instance
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
namespace_class.class_eval(&include_method_bindings)
|
70
|
+
else
|
71
|
+
class_eval(&include_method_bindings)
|
72
|
+
end
|
73
|
+
|
74
|
+
class_eval do
|
75
|
+
os_method_names.each do |method_name|
|
76
|
+
if namespace
|
77
|
+
namespace_class.class_eval do
|
78
|
+
define_method method_name do |*args, &block|
|
79
|
+
unbound_method = nil
|
80
|
+
|
81
|
+
host = namespace_instance.instance_variable_get(:@host)
|
82
|
+
os_method_cache = host.instance_variable_get(:@os_method_cache) || {}
|
83
|
+
|
84
|
+
if os_method_cache.key?("#{namespace}.#{method_name}")
|
85
|
+
unbound_method = os_method_cache["#{namespace}.#{method_name}"]
|
86
|
+
else
|
87
|
+
## Find the correct method to resolve based on the OS for the remote host.
|
88
|
+
defined_method_name = host.resolve_os_method_name(os_method_properties, method_name)
|
89
|
+
unless defined_method_name
|
90
|
+
raise NoMethodError, "undefined method `#{method_name}' for #{self.class}"
|
91
|
+
end
|
92
|
+
|
93
|
+
## Get reference to the unbound method defined in module
|
94
|
+
unbound_method = mod.instance_method(defined_method_name)
|
95
|
+
raise NoMethodError, "undefined method `#{method_name}' for #{self.class}" unless unbound_method
|
96
|
+
|
97
|
+
## Cache the unbound method on this host instance for faster resolution on
|
98
|
+
## the next invocation of this method
|
99
|
+
os_method_cache["#{namespace}.#{method_name}"] = unbound_method
|
100
|
+
host.instance_variable_set(:@os_method_cache, os_method_cache)
|
101
|
+
end
|
102
|
+
|
103
|
+
## Bind the method to host instance and
|
104
|
+
## call it with args and block
|
105
|
+
bind_method(unbound_method, *args, &block)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
else
|
109
|
+
define_method method_name do |*args, &block|
|
110
|
+
unbound_method = nil
|
111
|
+
|
112
|
+
host = self
|
113
|
+
os_method_cache = host.instance_variable_get(:@os_method_cache) || {}
|
114
|
+
|
115
|
+
if os_method_cache.key?(method_name)
|
116
|
+
unbound_method = os_method_cache[method_name]
|
117
|
+
else
|
118
|
+
## Find the correct method to resolve based on the OS for the remote host.
|
119
|
+
defined_method_name = host.resolve_os_method_name(os_method_properties, method_name)
|
120
|
+
raise NoMethodError, "undefined method `#{method_name}' for #{self.class}" unless defined_method_name
|
121
|
+
|
122
|
+
## Get reference to the unbound method defined in module
|
123
|
+
unbound_method = mod.instance_method(defined_method_name)
|
124
|
+
raise NoMethodError, "undefined method `#{method_name}' for #{self.class}" unless unbound_method
|
125
|
+
|
126
|
+
## Cache the unbound method on this host instance for faster resolution on
|
127
|
+
## the next invocation of this method
|
128
|
+
os_method_cache[method_name] = unbound_method
|
129
|
+
host.instance_variable_set(:@os_method_cache, os_method_cache)
|
130
|
+
end
|
131
|
+
|
132
|
+
## Bind the method to host instance and
|
133
|
+
## call it with args and block
|
134
|
+
bind_method(unbound_method, *args, &block)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def resolve_os_method_name(properties, method_name)
|
140
|
+
kernel = os.kernel.downcase
|
141
|
+
release = os.release.downcase
|
142
|
+
|
143
|
+
properties[method_name].each do |property|
|
144
|
+
os_name = property[:os_name]
|
145
|
+
strict = property[:options] ? property[:options][:strict] : false
|
146
|
+
except = property[:options] ? property[:options][:except] : ''
|
147
|
+
|
148
|
+
next if except && (except == release || except.include?(release))
|
149
|
+
|
150
|
+
if release == os_name || kernel == os_name ||
|
151
|
+
(Kanrisuru::Util::OsFamily.family_include_distribution?(os_name, release) && !strict) ||
|
152
|
+
(Kanrisuru::Util::OsFamily.upstream_include_distribution?(os_name, release) && !strict)
|
153
|
+
return property[:method_name]
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
nil
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|