kanrisuru 0.11.1 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -1
  3. data/CHANGELOG.md +9 -0
  4. data/README.md +13 -88
  5. data/kanrisuru.gemspec +1 -0
  6. data/lib/kanrisuru/command.rb +7 -0
  7. data/lib/kanrisuru/core/archive.rb +11 -35
  8. data/lib/kanrisuru/core/file.rb +4 -11
  9. data/lib/kanrisuru/core/find.rb +2 -6
  10. data/lib/kanrisuru/core/mount.rb +14 -15
  11. data/lib/kanrisuru/core/stream.rb +1 -2
  12. data/lib/kanrisuru/core/zypper.rb +6 -23
  13. data/lib/kanrisuru/os_package/collection.rb +58 -0
  14. data/lib/kanrisuru/os_package/define.rb +34 -0
  15. data/lib/kanrisuru/os_package/include.rb +163 -0
  16. data/lib/kanrisuru/os_package.rb +3 -245
  17. data/lib/kanrisuru/remote/fstab.rb +1 -1
  18. data/lib/kanrisuru/result.rb +5 -4
  19. data/lib/kanrisuru/version.rb +1 -1
  20. data/spec/functional/core/archive_spec.rb +2 -1
  21. data/spec/functional/core/mount_spec.rb +121 -0
  22. data/spec/helper/stub_network.rb +1 -1
  23. data/spec/helper/test_hosts.rb +11 -1
  24. data/spec/integration/core/apt_spec.rb +2 -3
  25. data/spec/integration/core/archive_spec.rb +8 -13
  26. data/spec/integration/core/disk_spec.rb +2 -3
  27. data/spec/integration/core/dmi_spec.rb +2 -3
  28. data/spec/integration/core/file_spec.rb +4 -13
  29. data/spec/integration/core/find_spec.rb +2 -3
  30. data/spec/integration/core/group_spec.rb +2 -3
  31. data/spec/integration/core/ip_spec.rb +2 -3
  32. data/spec/integration/core/path_spec.rb +2 -3
  33. data/spec/integration/core/socket_spec.rb +2 -4
  34. data/spec/integration/core/stat_spec.rb +2 -3
  35. data/spec/integration/core/stream_spec.rb +6 -9
  36. data/spec/integration/core/system_spec.rb +2 -3
  37. data/spec/integration/core/transfer_spec.rb +4 -9
  38. data/spec/integration/core/user_spec.rb +2 -4
  39. data/spec/integration/core/yum_spec.rb +2 -3
  40. data/spec/integration/core/zypper_spec.rb +2 -3
  41. data/spec/integration/remote/cpu_spec.rb +2 -3
  42. data/spec/integration/remote/env_spec.rb +2 -3
  43. data/spec/integration/remote/fstab_spec.rb +2 -3
  44. data/spec/integration/remote/host_spec.rb +2 -3
  45. data/spec/integration/remote/memory_spec.rb +2 -2
  46. data/spec/integration/remote/os_spec.rb +2 -3
  47. data/spec/integration/remote/remote_file_spec.rb +9 -15
  48. data/spec/spec_helper.rb +12 -3
  49. data/spec/unit/command_spec.rb +18 -0
  50. metadata +21 -3
@@ -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
@@ -1,247 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'set'
4
-
5
- module Kanrisuru
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'
@@ -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
@@ -40,13 +40,14 @@ module Kanrisuru
40
40
  end
41
41
 
42
42
  def to_i
43
- if @data.instance_of?(Integer)
43
+ case @data
44
+ when Integer
44
45
  @data
45
- elsif @data.instance_of?(String)
46
+ when String
46
47
  @data.to_i
47
- elsif @data.instance_of?(Array)
48
+ when Array
48
49
  @data.map(&:to_i)
49
- elsif @data.instance_of?(NilClass)
50
+ when NilClass
50
51
  nil
51
52
  else
52
53
  raise NoMethodError, "(undefined method `to_i' for Kanrisuru::Result)"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Kanrisuru
4
- VERSION = '0.11.1'
4
+ VERSION = '0.12.0'
5
5
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- RSpec.describe Kanrisuru::Core::Apt do
5
+ RSpec.describe Kanrisuru::Core::Archive do
6
6
  before(:all) do
7
7
  StubNetwork.stub!
8
8
  StubNetwork.stub_command!(:realpath) do |_args|
@@ -141,6 +141,7 @@ RSpec.describe Kanrisuru::Core::Apt do
141
141
  %w[diff compare d].each do |action_variant|
142
142
  expect_command(host.tar(action_variant, 'archive.tar', directory: directory),
143
143
  'tar --restrict -C /home/ubuntu/dir -f archive.tar -d')
144
+
144
145
  expect_command(host.tar(action_variant, 'archive.tar',
145
146
  directory: directory,
146
147
  occurrence: 4),
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Kanrisuru::Core::Mount do
6
+ before(:all) do
7
+ StubNetwork.stub!
8
+ end
9
+
10
+ after(:all) do
11
+ StubNetwork.unstub!
12
+ end
13
+
14
+ let(:host) do
15
+ Kanrisuru::Remote::Host.new(
16
+ host: 'localhost',
17
+ username: 'ubuntu',
18
+ keys: ['id_rsa']
19
+ )
20
+ end
21
+
22
+ it 'prepares mount command' do
23
+ expect_command(host.mount, 'mount')
24
+ expect_command(host.mount(bind_old: '/mnt/dira', bind_new: '/mnt/dirb'), 'mount --bind /mnt/dira /mnt/dirb')
25
+ expect_command(host.mount(rbind_old: '/mnt/dira', rbind_new: '/mnt/dirb'), 'mount --rbind /mnt/dira /mnt/dirb')
26
+ expect_command(host.mount(move_old: '/mnt/dira', move_new: '/mnt/dirb'), 'mount --move /mnt/dira /mnt/dirb')
27
+ expect_command(host.mount(
28
+ label: 'cloudimg-rootfs',
29
+ uuid: '5fbaea960d09e2ad',
30
+ sloppy: true,
31
+ internal_only: true,
32
+ fake: true,
33
+ no_mtab: true,
34
+ no_canonicalize: true,
35
+ device: '/dev/vda9',
36
+ directory: '/mnt/dir1'
37
+ ), 'mount -L cloudimg-rootfs -U 5fbaea960d09e2ad -f -i -s --no-mtab --no-canonicalize /dev/vda9 /mnt/dir1')
38
+
39
+ expect_command(host.mount(
40
+ fs_opts: { async: true, auto: true, group: true, relatime: true, owner: true },
41
+ device: '/dev/tty',
42
+ directory: '/mnt/dir2'
43
+ ), 'mount -o async,auto,group,relatime,owner /dev/tty /mnt/dir2')
44
+
45
+ expect do
46
+ host.mount(fs_opts: { value: true }, device: '/home/ubuntu/dir', directory: '/mnt/dir3')
47
+ end.to raise_error(ArgumentError)
48
+
49
+ expect_command(host.mount(
50
+ type: 'ext2',
51
+ device: '/dev/tty',
52
+ directory: '/mnt/dir2'
53
+ ), 'mount -t ext2 /dev/tty /mnt/dir2')
54
+
55
+ expect_command(host.mount(
56
+ type: 'ext4',
57
+ fs_opts: { acl: true, journal: 'update', usrquota: true, async: true, owner: true, group: true },
58
+ device: '/dev/tty',
59
+ directory: '/mnt/dir2'
60
+ ), 'mount -t ext4 -o acl,journal=update,usrquota,async,owner,group /dev/tty /mnt/dir2')
61
+
62
+ expect_command(host.mount(type: 'nontfs,xfs', all: true), 'mount -t nontfs,xfs -a')
63
+ expect_command(host.mount(type: 'fat,xfs', all: true), 'mount -t fat,xfs -a')
64
+
65
+ expect do
66
+ host.mount(
67
+ type: 'ext2',
68
+ fs_opts: { acl: true, journal: 'update', usrquota: true, async: true, owner: true, group: true },
69
+ device: '/dev/tty',
70
+ directory: '/mnt/dir2'
71
+ )
72
+ end.to raise_error(ArgumentError)
73
+
74
+ expect do
75
+ host.mount(
76
+ type: 'ext4',
77
+ fs_opts: { acl: true, journal: true, usrquota: true, async: true, owner: true, group: true },
78
+ device: '/dev/tty',
79
+ directory: '/mnt/dir2'
80
+ )
81
+ end.to raise_error(ArgumentError)
82
+
83
+ expect_command(host.mount(all: true, test_opts: { _netdev: true }), 'mount -a -O _netdev')
84
+ expect_command(host.mount(all: true, test_opts: { async: true, blocksize: 512, uid: 0, gid: 0, dots: true }, type: 'fat'),
85
+ 'mount -t fat -a -O async,blocksize=512,uid=0,gid=0,dots')
86
+
87
+ expect_command(host.mount(
88
+ type: 'loop',
89
+ fs_opts: { loop: '/dev/loop3' },
90
+ device: '/mnt',
91
+ directory: '/tmp/fdimage'
92
+ ),
93
+ 'mount -t loop -o loop=/dev/loop3 /mnt /tmp/fdimage')
94
+ end
95
+
96
+ it 'prepares umount command' do
97
+ expect_command(host.umount, 'umount')
98
+ expect_command(host.umount(
99
+ fake: true,
100
+ no_canonicalize: true,
101
+ no_mtab: true,
102
+ fail_remount_readonly: true,
103
+ free_loopback: true,
104
+ lazy: true,
105
+ force: true,
106
+ device: '/dev/vda1'
107
+ ),
108
+ 'umount --fake --no-canonicalize -n -r -d -l -f /dev/vda1')
109
+
110
+ expect_command(host.umount(
111
+ all: true,
112
+ type: 'ext4,nofat'
113
+ ), 'umount -a -t ext4,nofat')
114
+
115
+ expect_command(host.umount(
116
+ all: true,
117
+ type: 'ext4',
118
+ test_opts: { barrier: 1, nouid32: true }
119
+ ), 'umount -a -t ext4 -O barrier=1,nouid32')
120
+ end
121
+ end
@@ -33,7 +33,7 @@ class StubNetwork
33
33
  end
34
34
 
35
35
  return if Kanrisuru::Result.instance_methods(false).include?(:initialize_alias)
36
-
36
+
37
37
  Kanrisuru::Result.class_eval do
38
38
  alias_method :initialize_alias, :initialize
39
39
  def initialize(command, parse_result = false, &block)
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'securerandom'
4
+
3
5
  class TestHosts
4
6
  class << self
5
7
  def each_os(opts = {}, &block)
@@ -7,7 +9,10 @@ class TestHosts
7
9
  next unless test?(os_name)
8
10
  next if opts[:only] && !only?(opts, os_name)
9
11
 
10
- block.call(os_name)
12
+ host_json = TestHosts.host(os_name)
13
+ spec_dir = spec_dir(os_name, host_json)
14
+
15
+ block.call(os_name, host_json, spec_dir)
11
16
  end
12
17
  end
13
18
 
@@ -15,6 +20,11 @@ class TestHosts
15
20
  hosts(name)
16
21
  end
17
22
 
23
+ def spec_dir(os_name, host_json)
24
+ random_string = SecureRandom.hex
25
+ "#{host_json['home']}/.kanrisuru_spec_files_#{random_string[0..5]}"
26
+ end
27
+
18
28
  def only?(opts, name)
19
29
  ((opts[:only].instance_of?(Array) && opts[:only].include?(name)) ||
20
30
  (opts[:only].instance_of?(String) && opts[:only] == name))
@@ -2,10 +2,9 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- RSpec.describe Kanrisuru::Core::Apt do
6
- TestHosts.each_os(only: %w[debian ubuntu]) do |os_name|
5
+ TestHosts.each_os(only: %w[debian ubuntu]) do |os_name, host_json|
6
+ RSpec.describe Kanrisuru::Core::Apt do
7
7
  context "with #{os_name}" do
8
- let(:host_json) { TestHosts.host(os_name) }
9
8
  let(:host) do
10
9
  Kanrisuru::Remote::Host.new(
11
10
  host: host_json['hostname'],