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/os_package.rb
CHANGED
@@ -1,247 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
module OsPackage
|
7
|
-
module Define
|
8
|
-
def self.extended(base)
|
9
|
-
base.instance_variable_set(:@os_method_properties, {})
|
10
|
-
base.instance_variable_set(:@os_methods, Set.new)
|
11
|
-
end
|
12
|
-
|
13
|
-
def os_define(os_name, method_name, options = {})
|
14
|
-
unique_method_name = options[:alias] || method_name
|
15
|
-
|
16
|
-
@os_methods.add(method_name)
|
17
|
-
|
18
|
-
if @os_method_properties.key?(unique_method_name)
|
19
|
-
params = {
|
20
|
-
os_name: os_name.to_s,
|
21
|
-
method_name: method_name,
|
22
|
-
options: options
|
23
|
-
}
|
24
|
-
|
25
|
-
@os_method_properties[unique_method_name].prepend(params)
|
26
|
-
else
|
27
|
-
@os_method_properties[unique_method_name] = [{
|
28
|
-
os_name: os_name.to_s,
|
29
|
-
method_name: method_name,
|
30
|
-
options: options
|
31
|
-
}]
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
module Collection
|
37
|
-
def os_collection(mod, opts = {})
|
38
|
-
os_method_properties = mod.instance_variable_get(:@os_method_properties)
|
39
|
-
os_method_names = os_method_properties.keys
|
40
|
-
|
41
|
-
namespace = opts[:namespace]
|
42
|
-
namespace_instance = nil
|
43
|
-
|
44
|
-
if namespace
|
45
|
-
## Define the namespace as an eigen class instance on the host.
|
46
|
-
## Namespaced instances will access core host methods
|
47
|
-
## with @host instance variable.
|
48
|
-
|
49
|
-
if Kanrisuru::Remote::Cluster.instance_variable_defined?("@#{namespace}")
|
50
|
-
namespace_class = Kanrisuru::Remote::Cluster.const_get(Kanrisuru::Util.camelize(namespace))
|
51
|
-
namespace_instance = instance_variable_get("@#{namespace}")
|
52
|
-
else
|
53
|
-
namespace_class = Kanrisuru::Remote::Cluster.const_set(Kanrisuru::Util.camelize(namespace), Class.new)
|
54
|
-
namespace_instance = Kanrisuru::Remote::Cluster.instance_variable_set("@#{namespace}", namespace_class.new)
|
55
|
-
|
56
|
-
class_eval do
|
57
|
-
define_method namespace do
|
58
|
-
namespace_instance.instance_variable_set(:@cluster, self)
|
59
|
-
namespace_instance
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
namespace_class.class_eval do
|
65
|
-
os_method_names.each do |method_name|
|
66
|
-
define_method method_name do |*args, &block|
|
67
|
-
cluster = namespace_instance.instance_variable_get(:@cluster)
|
68
|
-
hosts = cluster.instance_variable_get(:@hosts)
|
69
|
-
hosts.map do |host_addr, host|
|
70
|
-
{ host: host_addr, result: host.send(namespace).send(method_name, *args, &block) }
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
else
|
76
|
-
class_eval do
|
77
|
-
os_method_names.each do |method_name|
|
78
|
-
define_method method_name do |*args, &block|
|
79
|
-
@hosts.map do |host_addr, host|
|
80
|
-
{ host: host_addr, result: host.send(method_name, *args, &block) }
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
module Include
|
90
|
-
def os_include(mod, opts = {})
|
91
|
-
os_method_properties = mod.instance_variable_get(:@os_method_properties)
|
92
|
-
os_method_names = os_method_properties.keys
|
93
|
-
|
94
|
-
## Need to encapsulate any helper methods called in the module
|
95
|
-
## to bind to the host instance. This acts as a psudeo module include.
|
96
|
-
os_methods = mod.instance_variable_get(:@os_methods)
|
97
|
-
|
98
|
-
public_methods = mod.instance_methods(false) - os_methods.to_a
|
99
|
-
private_methods = mod.private_instance_methods(false)
|
100
|
-
protected_methods = mod.protected_instance_methods(false)
|
101
|
-
include_methods = (public_methods + protected_methods + private_methods).flatten
|
102
|
-
|
103
|
-
include_method_bindings = proc do
|
104
|
-
include_methods.each do |method_name|
|
105
|
-
define_method method_name do |*args, &block|
|
106
|
-
unbound_method = mod.instance_method(method_name)
|
107
|
-
bind_method(unbound_method, *args, &block)
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
private_methods.each { |method_name| private(method_name) }
|
112
|
-
protected_methods.each { |method_name| protected(method_name) }
|
113
|
-
|
114
|
-
private
|
115
|
-
if RUBY_VERSION < '2.7'
|
116
|
-
define_method 'bind_method' do |unbound_method, *args, &block|
|
117
|
-
unbound_method.bind(self).call(*args, &block)
|
118
|
-
end
|
119
|
-
else
|
120
|
-
define_method 'bind_method' do |unbound_method, *args, &block|
|
121
|
-
unbound_method.bind_call(self, *args, &block)
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
namespace = opts[:namespace]
|
127
|
-
namespace_class = nil
|
128
|
-
namespace_instance = nil
|
129
|
-
|
130
|
-
if namespace
|
131
|
-
## Define the namespace as an eigen class instance within the host class.
|
132
|
-
## Namespaced instances will access core host methods
|
133
|
-
## with @host instance variable.
|
134
|
-
|
135
|
-
## Check to see if the namespace was defined. If so, additional methods will be appended to the
|
136
|
-
## existing namespace class definition, otherwise, a new namespace class and instance will be
|
137
|
-
## defined with the methods added.
|
138
|
-
if Kanrisuru::Remote::Host.instance_variable_defined?("@#{namespace}")
|
139
|
-
namespace_class = Kanrisuru::Remote::Host.const_get(Kanrisuru::Util.camelize(namespace))
|
140
|
-
namespace_instance = Kanrisuru::Remote::Host.instance_variable_get("@#{namespace}")
|
141
|
-
else
|
142
|
-
namespace_class = Kanrisuru::Remote::Host.const_set(Kanrisuru::Util.camelize(namespace), Class.new)
|
143
|
-
namespace_instance = Kanrisuru::Remote::Host.instance_variable_set("@#{namespace}", namespace_class.new)
|
144
|
-
|
145
|
-
class_eval do
|
146
|
-
define_method namespace do
|
147
|
-
namespace_instance.instance_variable_set(:@host, self)
|
148
|
-
namespace_instance
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
namespace_class.class_eval(&include_method_bindings)
|
154
|
-
else
|
155
|
-
class_eval(&include_method_bindings)
|
156
|
-
end
|
157
|
-
|
158
|
-
class_eval do
|
159
|
-
os_method_names.each do |method_name|
|
160
|
-
if namespace
|
161
|
-
namespace_class.class_eval do
|
162
|
-
define_method method_name do |*args, &block|
|
163
|
-
unbound_method = nil
|
164
|
-
|
165
|
-
host = namespace_instance.instance_variable_get(:@host)
|
166
|
-
os_method_cache = host.instance_variable_get(:@os_method_cache) || {}
|
167
|
-
|
168
|
-
if os_method_cache.key?("#{namespace}.#{method_name}")
|
169
|
-
unbound_method = os_method_cache["#{namespace}.#{method_name}"]
|
170
|
-
else
|
171
|
-
## Find the correct method to resolve based on the OS for the remote host.
|
172
|
-
defined_method_name = host.resolve_os_method_name(os_method_properties, method_name)
|
173
|
-
unless defined_method_name
|
174
|
-
raise NoMethodError, "undefined method `#{method_name}' for #{self.class}"
|
175
|
-
end
|
176
|
-
|
177
|
-
## Get reference to the unbound method defined in module
|
178
|
-
unbound_method = mod.instance_method(defined_method_name)
|
179
|
-
raise NoMethodError, "undefined method `#{method_name}' for #{self.class}" unless unbound_method
|
180
|
-
|
181
|
-
## Cache the unbound method on this host instance for faster resolution on
|
182
|
-
## the next invocation of this method
|
183
|
-
os_method_cache["#{namespace}.#{method_name}"] = unbound_method
|
184
|
-
host.instance_variable_set(:@os_method_cache, os_method_cache)
|
185
|
-
end
|
186
|
-
|
187
|
-
## Bind the method to host instance and
|
188
|
-
## call it with args and block
|
189
|
-
bind_method(unbound_method, *args, &block)
|
190
|
-
end
|
191
|
-
end
|
192
|
-
else
|
193
|
-
define_method method_name do |*args, &block|
|
194
|
-
unbound_method = nil
|
195
|
-
|
196
|
-
host = self
|
197
|
-
os_method_cache = host.instance_variable_get(:@os_method_cache) || {}
|
198
|
-
|
199
|
-
if os_method_cache.key?(method_name)
|
200
|
-
unbound_method = os_method_cache[method_name]
|
201
|
-
else
|
202
|
-
## Find the correct method to resolve based on the OS for the remote host.
|
203
|
-
defined_method_name = host.resolve_os_method_name(os_method_properties, method_name)
|
204
|
-
raise NoMethodError, "undefined method `#{method_name}' for #{self.class}" unless defined_method_name
|
205
|
-
|
206
|
-
## Get reference to the unbound method defined in module
|
207
|
-
unbound_method = mod.instance_method(defined_method_name)
|
208
|
-
raise NoMethodError, "undefined method `#{method_name}' for #{self.class}" unless unbound_method
|
209
|
-
|
210
|
-
## Cache the unbound method on this host instance for faster resolution on
|
211
|
-
## the next invocation of this method
|
212
|
-
os_method_cache[method_name] = unbound_method
|
213
|
-
host.instance_variable_set(:@os_method_cache, os_method_cache)
|
214
|
-
end
|
215
|
-
|
216
|
-
## Bind the method to host instance and
|
217
|
-
## call it with args and block
|
218
|
-
bind_method(unbound_method, *args, &block)
|
219
|
-
end
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
def resolve_os_method_name(properties, method_name)
|
224
|
-
kernel = os.kernel.downcase
|
225
|
-
release = os.release.downcase
|
226
|
-
|
227
|
-
properties[method_name].each do |property|
|
228
|
-
os_name = property[:os_name]
|
229
|
-
strict = property[:options] ? property[:options][:strict] : false
|
230
|
-
except = property[:options] ? property[:options][:except] : ''
|
231
|
-
|
232
|
-
next if except && (except == release || except.include?(release))
|
233
|
-
|
234
|
-
if release == os_name || kernel == os_name ||
|
235
|
-
(Kanrisuru::Util::OsFamily.family_include_distribution?(os_name, release) && !strict) ||
|
236
|
-
(Kanrisuru::Util::OsFamily.upstream_include_distribution?(os_name, release) && !strict)
|
237
|
-
return property[:method_name]
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
nil
|
242
|
-
end
|
243
|
-
end
|
244
|
-
end
|
245
|
-
end
|
246
|
-
end
|
247
|
-
end
|
3
|
+
require_relative 'os_package/collection'
|
4
|
+
require_relative 'os_package/define'
|
5
|
+
require_relative 'os_package/include'
|
data/lib/kanrisuru/remote/cpu.rb
CHANGED
@@ -27,6 +27,10 @@ module Kanrisuru
|
|
27
27
|
load_average[2]
|
28
28
|
end
|
29
29
|
|
30
|
+
def architecture
|
31
|
+
@cpu_architecture.architecture
|
32
|
+
end
|
33
|
+
|
30
34
|
def sockets
|
31
35
|
@cpu_architecture.sockets
|
32
36
|
end
|
@@ -103,7 +107,7 @@ module Kanrisuru
|
|
103
107
|
@cpu_architecture.flags
|
104
108
|
end
|
105
109
|
|
106
|
-
|
110
|
+
def hyperthreading?
|
107
111
|
threads_per_core > 1
|
108
112
|
end
|
109
113
|
|
@@ -161,7 +161,7 @@ module Kanrisuru
|
|
161
161
|
|
162
162
|
if Kanrisuru::Util.present?(@line) && @line.instance_of?(String)
|
163
163
|
parse_line!
|
164
|
-
elsif Kanrisuru::Util.present?(@opts) && @opts.instance_of?(String) || @opts.instance_of?(Hash)
|
164
|
+
elsif (Kanrisuru::Util.present?(@opts) && @opts.instance_of?(String)) || @opts.instance_of?(Hash)
|
165
165
|
@opts = Kanrisuru::Remote::Fstab::Options.new(@type, @opts)
|
166
166
|
end
|
167
167
|
end
|
@@ -255,7 +255,7 @@ module Kanrisuru
|
|
255
255
|
end
|
256
256
|
|
257
257
|
result = @host.blkid(device: @device)
|
258
|
-
@uuid = result.success? ? result.uuid : nil
|
258
|
+
@uuid = result.success? ? result[0].uuid : nil
|
259
259
|
end
|
260
260
|
|
261
261
|
def parse_uuid(fsline)
|
@@ -269,15 +269,15 @@ module Kanrisuru
|
|
269
269
|
end
|
270
270
|
|
271
271
|
result = @host.blkid(device: @device)
|
272
|
-
@label = result.success? ? result.label : nil
|
272
|
+
@label = result.success? ? result[0].label : nil
|
273
273
|
end
|
274
274
|
|
275
275
|
def parse_dev(fsline)
|
276
276
|
@device = fsline
|
277
277
|
result = @host.blkid(device: @device)
|
278
278
|
|
279
|
-
@label = result.success? ? result.label : nil
|
280
|
-
@uuid = result.success? ? result.uuid : nil
|
279
|
+
@label = result.success? ? result[0].label : nil
|
280
|
+
@uuid = result.success? ? result[0].uuid : nil
|
281
281
|
end
|
282
282
|
end
|
283
283
|
|
data/lib/kanrisuru/result.rb
CHANGED
@@ -40,13 +40,14 @@ module Kanrisuru
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def to_i
|
43
|
-
|
43
|
+
case @data
|
44
|
+
when Integer
|
44
45
|
@data
|
45
|
-
|
46
|
+
when String
|
46
47
|
@data.to_i
|
47
|
-
|
48
|
+
when Array
|
48
49
|
@data.map(&:to_i)
|
49
|
-
|
50
|
+
when NilClass
|
50
51
|
nil
|
51
52
|
else
|
52
53
|
raise NoMethodError, "(undefined method `to_i' for Kanrisuru::Result)"
|
data/lib/kanrisuru/util.rb
CHANGED
data/lib/kanrisuru/version.rb
CHANGED
@@ -22,10 +22,9 @@ RSpec.describe Kanrisuru::Core::Apt do
|
|
22
22
|
it 'prepares apt list command' do
|
23
23
|
expect_command(host.apt('list'), 'apt list')
|
24
24
|
expect_command(host.apt('list',
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
), 'apt list --installed --upgradeable --all-versions')
|
25
|
+
installed: true,
|
26
|
+
upgradeable: true,
|
27
|
+
all_versions: true), 'apt list --installed --upgradeable --all-versions')
|
29
28
|
|
30
29
|
expect_command(host.apt('list', package_name: 'nginx'), 'apt list -a nginx')
|
31
30
|
end
|
@@ -43,28 +42,22 @@ RSpec.describe Kanrisuru::Core::Apt do
|
|
43
42
|
end
|
44
43
|
|
45
44
|
it 'prepares apt install command' do
|
46
|
-
expect_command(host.apt('install',
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
expect_command(host.apt('install',
|
61
|
-
packages: ['build-essential', 'manpages-dev'],
|
62
|
-
only_upgrade: true,
|
63
|
-
),
|
64
|
-
'apt-get install -y --only-upgrade build-essential manpages-dev'
|
65
|
-
)
|
45
|
+
expect_command(host.apt('install',
|
46
|
+
packages: 'nginx'),
|
47
|
+
'apt-get install -y nginx')
|
48
|
+
|
49
|
+
expect_command(host.apt('install',
|
50
|
+
packages: 'monit',
|
51
|
+
no_upgrade: true,
|
52
|
+
reinstall: true),
|
53
|
+
'apt-get install -y --no-upgrade --reinstall monit')
|
54
|
+
|
55
|
+
expect_command(host.apt('install',
|
56
|
+
packages: %w[build-essential manpages-dev],
|
57
|
+
only_upgrade: true),
|
58
|
+
'apt-get install -y --only-upgrade build-essential manpages-dev')
|
66
59
|
end
|
67
|
-
|
60
|
+
|
68
61
|
it 'prepares apt remove command' do
|
69
62
|
expect_command(host.apt('remove', packages: ['python']), 'apt-get remove -y python')
|
70
63
|
end
|
@@ -82,15 +75,14 @@ RSpec.describe Kanrisuru::Core::Apt do
|
|
82
75
|
end
|
83
76
|
|
84
77
|
it 'prepares apt show command' do
|
85
|
-
expect_command(host.apt('show', packages: 'ruby'), 'apt show -a ruby')
|
86
|
-
end
|
78
|
+
expect_command(host.apt('show', packages: 'ruby'), 'apt show -a ruby')
|
79
|
+
end
|
87
80
|
|
88
81
|
it 'prepares apt clean command' do
|
89
|
-
expect_command(host.apt('clean'), 'apt-get clean')
|
82
|
+
expect_command(host.apt('clean'), 'apt-get clean')
|
90
83
|
end
|
91
84
|
|
92
85
|
it 'prepares apt autoclean command' do
|
93
|
-
expect_command(host.apt('autoclean'), 'apt-get autoclean')
|
86
|
+
expect_command(host.apt('autoclean'), 'apt-get autoclean')
|
94
87
|
end
|
95
|
-
|
96
88
|
end
|