kanrisuru 0.10.0 → 0.12.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|