kitchen-qemu 0.1.3 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ae36680bcd2808d461d0d57e9be6d0c55a919c43
4
- data.tar.gz: 05b1439ddc31ba48f31b607e2bb96607c428d5ab
3
+ metadata.gz: a4524644c5f8decc92563913b719bed878cb8481
4
+ data.tar.gz: 48e60f381449ce1e9b9b123d7874d24b4d5b67c2
5
5
  SHA512:
6
- metadata.gz: e4013ca5ceba2813668ea367f656baa9bb6d9d7886d885c93ddf4112a32863f3796a43e0d1425735d43406203900e34c9b1b88c1f2d832f01f42b90273dd6b32
7
- data.tar.gz: 029c25cec633dcd7ba9d2a7fc3ca4b5ec9a6a8be80c82691ec43bfb40a1e76fa245a2d93a60ca2e898c5af687d967f342992549dc858563ec81c627d76e9d9c3
6
+ metadata.gz: 82fe2072030831acf5700f87178a8a889485dc949c8254540306dd9e290be1b657fd609688765ef85e548bfde5f1c9fb47a9df7cd26686035dac62639dccc244
7
+ data.tar.gz: 43b5e78b3dfb446405e0f2d809b33db8281fc44636851782c421d82321bbbbef755ea60149d0e4007e14c78ef4ea1c3293d3ddd961891a96622a7163a4251797
@@ -33,13 +33,14 @@ module Kitchen
33
33
  kitchen_driver_api_version 2
34
34
  plugin_version Kitchen::Driver::QEMU_VERSION
35
35
 
36
- default_config :arch, 'x86_64'
37
- default_config :username, 'kitchen'
38
- default_config :password, 'kitchen'
39
- default_config :port, 2222
40
- default_config :display, 'none'
41
- default_config :memory, '512'
42
- default_config :nic_model, 'virtio'
36
+ default_config :arch, 'x86_64'
37
+ default_config :username, 'kitchen'
38
+ default_config :password, 'kitchen'
39
+ default_config :port, 2222
40
+ default_config :display, 'none'
41
+ default_config :memory, '512'
42
+ default_config :nic_model, 'virtio'
43
+ default_config :hostshares, []
43
44
 
44
45
  required_config :image do |_attr, value, _subject|
45
46
  raise UserError, 'Must specify image file' unless value
@@ -60,6 +61,52 @@ module Kitchen
60
61
  config[:binary] = @@ARCHBINARY[config[:arch]] or
61
62
  raise UserError, "Unknown architecture '#{config[:arch]}'"
62
63
  end
64
+
65
+ # kitchen-vagrant compatibility
66
+ config[:hostname] = config[:vm_hostname] if config[:hostname].nil?
67
+
68
+ acpi_poweroff = false
69
+ if config[:image].kind_of?(String)
70
+ config[:image] = [{
71
+ :file => config[:image],
72
+ :readonly => true,
73
+ :snapshot => true,
74
+ }]
75
+ else
76
+ raise UserError, "Invalid image entry for #{instance.to_str}" unless
77
+ config[:image].kind_of?(Array)
78
+ config[:image].each do |image|
79
+ raise UserError, "Invalid image entry for #{instance.to_str}" unless
80
+ image.kind_of?(Hash) && image[:file]
81
+ image[:snapshot] = true if image[:snapshot].nil?
82
+ image[:readonly] = image[:snapshot] if image[:readonly].nil?
83
+ acpi_poweroff = true unless image[:readonly]
84
+ end
85
+ end
86
+ config[:acpi_poweroff] = acpi_poweroff if config[:acpi_poweroff].nil?
87
+
88
+ raise UserError, "Invalid share entry for #{instance.to_str}" unless
89
+ config[:hostshares].kind_of?(Array)
90
+ # kitchen-vagrant compatibility
91
+ if config[:hostshares].empty? && config[:synced_folders].kind_of?(Array)
92
+ config[:synced_folders].each do |folder|
93
+ if !folder[0].kind_of?(String) || !folder[1].kind_of?(String)
94
+ config[:hostshares].clear
95
+ break
96
+ end
97
+ config[:hostshares].push({ :path => folder[0], :mountpoint => folder[1] })
98
+ end
99
+ else
100
+ config[:hostshares].each do |share|
101
+ raise UserError, "Invalid share entry for #{instance.to_str}" unless
102
+ share.kind_of?(Hash) && share[:path]
103
+ raise UserError, "No mountpoint defined for share '#{share[:path]}' of #{instance.to_str}" unless
104
+ share[:mountpoint]
105
+ raise UserError, "Invalid mount options for share '#{share[:path]}' of #{instance.to_str}" unless
106
+ share[:mount_options].nil? || share[:mount_options].kind_of?(Array)
107
+ end
108
+ end
109
+
63
110
  config[:vga] = 'qxl' if config[:spice] && !config[:vga]
64
111
  self
65
112
  end
@@ -69,7 +116,7 @@ module Kitchen
69
116
  # @param state [Hash] mutable instance and driver state
70
117
  # @raise [ActionFailed] if the action could not be completed
71
118
  def create(state)
72
- monitor = monitor_qmp_path
119
+ monitor = monitor_path
73
120
  if File.exist?(monitor)
74
121
  begin
75
122
  mon = UNIXSocket.new(monitor)
@@ -84,28 +131,24 @@ module Kitchen
84
131
 
85
132
  create_privkey or raise ActionFailed, "Unable to create file '#{privkey_path}'"
86
133
 
87
- fqdn = config[:vm_hostname] || instance.name
134
+ fqdn = config[:hostname] || instance.name
88
135
  hostname = fqdn.match(/^([^.]+)/)[0]
89
136
 
90
- state[:hostname] = 'localhost'
91
- state[:port] = config[:port]
92
- state[:username] = config[:username]
93
- state[:password] = config[:password]
137
+ state[:hostname] = 'localhost'
138
+ state[:port] = config[:port]
139
+ state[:username] = config[:username]
140
+ state[:password] = config[:password]
141
+ state[:acpi_poweroff] = config[:acpi_poweroff]
94
142
 
95
143
  cmd = [
96
144
  config[:binary], '-daemonize',
97
145
  '-display', config[:display].to_s,
98
146
  '-chardev', "socket,id=mon-qmp,path=#{monitor},server,nowait",
99
147
  '-mon', 'chardev=mon-qmp,mode=control,default',
100
- '-chardev', "socket,id=mon-rdl,path=#{monitor_readline_path},server,nowait",
101
- '-mon', 'chardev=mon-rdl,mode=readline',
148
+ '-serial', "mon:unix:path=#{serial_path},server,nowait",
102
149
  '-m', config[:memory].to_s,
103
150
  '-net', "nic,model=#{config[:nic_model]}",
104
151
  '-net', "user,net=192.168.1.0/24,hostname=#{hostname},hostfwd=tcp::#{state[:port]}-:22",
105
- '-device', 'virtio-scsi-pci,id=scsi',
106
- '-device', 'scsi-hd,drive=root',
107
- '-drive', "if=none,id=root,readonly,file=#{config[:image]}",
108
- '-snapshot',
109
152
  ]
110
153
 
111
154
  kvm = config[:kvm]
@@ -131,6 +174,25 @@ module Kitchen
131
174
  cmd.push('-spice', config[:spice].to_s) if config[:spice]
132
175
  cmd.push('-vnc', config[:vnc].to_s) if config[:vnc]
133
176
 
177
+ cmd.push('-device', 'virtio-scsi-pci,id=scsi')
178
+ config[:image].each_with_index do |image, i|
179
+ drive = ['if=none', "id=drive#{i}"]
180
+ drive.push('readonly') if image[:readonly]
181
+ drive.push('snapshot=on') if image[:snapshot]
182
+ drive.push("file=#{image[:file]}")
183
+ cmd.push('-device', "scsi-hd,drive=drive#{i}",
184
+ '-drive', drive.join(','))
185
+ end
186
+
187
+ config[:hostshares].each_with_index do |share, i|
188
+ path = share[:path]
189
+ path = "#{config[:kitchen_root]}/#{path}" unless path[0] == '/'
190
+ raise ActionFailed, "Share path '#{path}' not a directory" unless
191
+ ::File.directory?(path)
192
+ cmd.push('-fsdev', "local,id=fsdev#{i},security_model=none,path=#{path}",
193
+ '-device', "virtio-9p-pci,fsdev=fsdev#{i},mount_tag=path#{i}")
194
+ end
195
+
134
196
  info 'Spawning QEMU..'
135
197
  error = nil
136
198
  Open3.popen3({ 'QEMU_AUDIO_DRV' => 'none' }, *cmd) do |_, _, err, thr|
@@ -155,6 +217,11 @@ module Kitchen
155
217
  conn.execute("sudo sh -c 'echo 127.0.0.1 #{names} >> /etc/hosts; hostnamectl set-hostname #{hostname} || hostname #{hostname} || true' 2>/dev/null")
156
218
  conn.execute('install -dm700 "$HOME/.ssh"')
157
219
  conn.execute("echo '#{@@PUBKEY}' > \"$HOME/.ssh/authorized_keys\"")
220
+ config[:hostshares].each_with_index do |share, i|
221
+ options = share[:mount_options] ?
222
+ share[:mount_options].join(',') : 'cache=none,access=any,version=9p2000.L'
223
+ conn.execute("sudo sh -c 'install -dm755 \"#{share[:mountpoint]}\" && mount -t 9p -o trans=virtio,#{options} path#{i} \"#{share[:mountpoint]}\"'")
224
+ end
158
225
  conn.close
159
226
  state[:ssh_key] = privkey_path
160
227
  end
@@ -164,16 +231,22 @@ module Kitchen
164
231
  # @param state [Hash] mutable instance state
165
232
  # @raise [ActionFailed] if the action could not be completed
166
233
  def destroy(state)
167
- monitor = monitor_qmp_path
234
+ monitor = monitor_path
168
235
  return unless File.exist?(monitor)
169
236
 
170
237
  instance.transport.connection(state).close
171
238
 
172
239
  begin
173
240
  mon = QMPClient.new(UNIXSocket.new(monitor), 2)
174
- info 'Quitting QEMU..'
175
- mon.execute('quit')
176
- mon.wait_for_eof(5)
241
+ if state[:acpi_poweroff]
242
+ info 'Sending ACPI poweroff..'
243
+ mon.execute('system_powerdown')
244
+ mon.wait_for_eof(30)
245
+ else
246
+ info 'Quitting QEMU..'
247
+ mon.execute('quit')
248
+ mon.wait_for_eof(5)
249
+ end
177
250
  mon.close
178
251
  rescue Errno::ECONNREFUSED
179
252
  info 'Connection to monitor refused. Assuming QEMU already quit.'
@@ -231,11 +304,11 @@ tY4IM9IaSC2LuPFVc0Kx6TwObdeQScOokIxL3HfayfLKieTLC+w2
231
304
  File.join(config[:kitchen_root], '.kitchen', 'kitchen-qemu.key')
232
305
  end
233
306
 
234
- def monitor_qmp_path
307
+ def monitor_path
235
308
  File.join(config[:kitchen_root], '.kitchen', "#{instance.name}.qmp")
236
309
  end
237
310
 
238
- def monitor_readline_path
311
+ def serial_path
239
312
  File.join(config[:kitchen_root], '.kitchen', "#{instance.name}.mon")
240
313
  end
241
314
 
@@ -247,12 +320,12 @@ tY4IM9IaSC2LuPFVc0Kx6TwObdeQScOokIxL3HfayfLKieTLC+w2
247
320
 
248
321
  def cleanup!
249
322
  begin
250
- File.delete(monitor_qmp_path)
323
+ File.delete(monitor_path)
251
324
  rescue Errno::ENOENT
252
325
  # do nothing
253
326
  end
254
327
  begin
255
- File.delete(monitor_readline_path)
328
+ File.delete(serial_path)
256
329
  rescue Errno::ENOENT
257
330
  # do nothing
258
331
  end
@@ -17,6 +17,6 @@
17
17
  module Kitchen
18
18
  module Driver
19
19
  # Version string for the QEMU Kitchen driver
20
- QEMU_VERSION = '0.1.3'
20
+ QEMU_VERSION = '0.2.0'
21
21
  end
22
22
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kitchen-qemu
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emil Renner Berthing
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-24 00:00:00.000000000 Z
11
+ date: 2016-03-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: test-kitchen