qemu-toolkit 0.3.5 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/doc/README.7 CHANGED
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "QEMU\-TOOLKIT" "7" "December 2012" "" "qemu-toolkit"
4
+ .TH "QEMU\-TOOLKIT" "7" "April 2013" "" "qemu-toolkit"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBqemu\-toolkit\fR \- A toolkit for running qemu on Illumos / OmniOS
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "QEMU\-TOOLKIT\-CONFIGURATION" "7" "December 2012" "" "qemu-toolkit"
4
+ .TH "QEMU\-TOOLKIT\-CONFIGURATION" "7" "April 2013" "" "qemu-toolkit"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBqemu\-toolkit\-configuration\fR \- configuration for qemu\-toolkit
@@ -46,6 +46,25 @@ lan \'vm1\', \'1:8:20:52:a6:7e\'
46
46
  .
47
47
  .SS "available options"
48
48
  Here\'s a list of configuration options within the virtual_machine declaration:
49
+ .
50
+ .TP
51
+ boot \fIOPTIONS\fR
52
+ Configures the boot order of the virtual machine\. Use the \'order\' option to configure boot order; use the \'once\' option to configure the first boot of the machine\. For more options, please see the QEMU documentation on \'\-boot\'\.
53
+ .
54
+ .IP "" 4
55
+ .
56
+ .nf
57
+
58
+ # Boot off the CDROM device, alyways
59
+ boot order: \'d\'
60
+
61
+ # Boot off the CDROM the next time, otherwise from harddisk first
62
+ boot order: \'c\', once: \'dc\'
63
+ .
64
+ .fi
65
+ .
66
+ .IP "" 0
67
+
49
68
  .
50
69
  .TP
51
70
  cpus \fINUMBER\fR
@@ -155,7 +174,13 @@ Add a virtual network card to the guest\. Virtual network cards are made to corr
155
174
  The \fBvia:\fR option takes either physical links or etherstub switches as value\. You can also specify a VLAN tag, separated by a colon\. (ie: e1000g0:4)
156
175
  .
157
176
  .IP
158
- nic \fBmodel:\fR will default to \fBvirtio\fR\.
177
+ You \fImust\fR specify a \fBmacaddr:\fR option using an address that is unique on your network\. No checking is done for this in qemu\-toolkit\. This is a limitation that will be lifted in future versions\.
178
+ .
179
+ .IP
180
+ nic \fBmodel:\fR will default to \fBvirtio\fR\. The \fBvirtio\fR driver will be configured for maximum throughput by setting driver options directly as smartos does\. This optimisation may change over time, but will always try to optimise throughput and availability\.
181
+ .
182
+ .IP
183
+ To configure the DHCP server that kvm has built in, use \fBip:\fR, \fBnetmask:\fR, \fBgateway:\fR, \fBhostname:\fR and \fBdns_ip:\fR options\. Please see the example below\.
159
184
  .
160
185
  .IP
161
186
  NOTE: QEMU/kvm on Illumos will default to providing a single pseudo\-nic that has a DHCP server attached to it by default\. If you do not specify a \fBnic\fR, this is what you\'ll get\.
@@ -166,6 +191,11 @@ NOTE: QEMU/kvm on Illumos will default to providing a single pseudo\-nic that ha
166
191
 
167
192
  # Create eth0 interface with given mac address via \'igb1\'\.
168
193
  nic \'eth0\', macaddr: \'2:8:20:52:a6:7e\', via: \'igb1\'
194
+
195
+ # Create an interface and provide the IP address by built\-in DHCP
196
+ nic \'eth1\', macaddr: \'\.\.\.\', via: \'igb2\',
197
+ ip: \'10\.0\.0\.2\', netmask: \'255\.255\.255\.0\', gateway: \'10\.0\.0\.1\',
198
+ hostname: \'test\', dns_ip0: \'8\.8\.8\.8\', dns_ip1: \'8\.8\.4\.4\'
169
199
  .
170
200
  .fi
171
201
  .
@@ -31,6 +31,18 @@ calls. Here's an example we've used in the wild:
31
31
 
32
32
  Here's a list of configuration options within the virtual_machine declaration:
33
33
 
34
+ * boot <OPTIONS>:
35
+ Configures the boot order of the virtual machine. Use the 'order' option
36
+ to configure boot order; use the 'once' option to configure the first
37
+ boot of the machine. For more options, please see the QEMU documentation
38
+ on '-boot'.
39
+
40
+ # Boot off the CDROM device, alyways
41
+ boot order: 'd'
42
+
43
+ # Boot off the CDROM the next time, otherwise from harddisk first
44
+ boot order: 'c', once: 'dc'
45
+
34
46
  * cpus <NUMBER>:
35
47
  Configures the number of SMP cpus simulated to the guest system.
36
48
  You should not configure more SMP cpus than you have physical CPU cores
@@ -91,10 +103,21 @@ Here's a list of configuration options within the virtual_machine declaration:
91
103
  option here.
92
104
 
93
105
  The `via:` option takes either physical links or etherstub switches as
94
- value.
95
- You can also specify a VLAN tag, separated by a colon. (ie: e1000g0:4)
106
+ value. You can also specify a VLAN tag, separated by a colon.
107
+ (ie: e1000g0:4)
108
+
109
+ You *must* specify a `macaddr:` option using an address that is unique
110
+ on your network. No checking is done for this in qemu-toolkit. This is
111
+ a limitation that will be lifted in future versions.
96
112
 
97
- nic `model:` will default to `virtio`.
113
+ nic `model:` will default to `virtio`. The `virtio` driver will be
114
+ configured for maximum throughput by setting driver options directly
115
+ as smartos does. This optimisation may change over time, but will always
116
+ try to optimise throughput and availability.
117
+
118
+ To configure the DHCP server that kvm has built in, use `ip:`,
119
+ `netmask:`, `gateway:`, `hostname:` and `dns_ip:` options. Please see the
120
+ example below.
98
121
 
99
122
  NOTE: QEMU/kvm on Illumos will default to providing a single pseudo-nic
100
123
  that has a DHCP server attached to it by default. If you do not specify
@@ -103,6 +126,11 @@ Here's a list of configuration options within the virtual_machine declaration:
103
126
  # Create eth0 interface with given mac address via 'igb1'.
104
127
  nic 'eth0', macaddr: '2:8:20:52:a6:7e', via: 'igb1'
105
128
 
129
+ # Create an interface and provide the IP address by built-in DHCP
130
+ nic 'eth1', macaddr: '...', via: 'igb2',
131
+ ip: '10.0.0.2', netmask: '255.255.255.0', gateway: '10.0.0.1',
132
+ hostname: 'test', dns_ip0: '8.8.8.8', dns_ip1: '8.8.4.4'
133
+
106
134
  * ram <MEGABYTES>:
107
135
  Configures the amount of RAM the guest system sees. Note that the qemu
108
136
  on Illumos locks memory down for the guest and never swaps it out. This
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "QEMU\-TOOLKIT\-INSTALL" "7" "November 2012" "" "qemu-toolkit"
4
+ .TH "QEMU\-TOOLKIT\-INSTALL" "7" "March 2013" "" "qemu-toolkit"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBqemu\-toolkit\-install\fR \- installations instructions for the qemu\-toolkit
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "QEMU\-TOOLKIT\-OVERVIEW" "7" "November 2012" "" "qemu-toolkit"
4
+ .TH "QEMU\-TOOLKIT\-OVERVIEW" "7" "March 2013" "" "qemu-toolkit"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBqemu\-toolkit\-overview\fR \- architecture and philosophy of qemu\-toolkit
data/doc/storadm.1 CHANGED
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "STORADM" "1" "November 2012" "" "qemu-toolkit"
4
+ .TH "STORADM" "1" "March 2013" "" "qemu-toolkit"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBstoradm\fR \- manages virtual machine storage
data/doc/vmadm.1 CHANGED
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "VMADM" "1" "November 2012" "" "qemu-toolkit"
4
+ .TH "VMADM" "1" "March 2013" "" "qemu-toolkit"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBvmadm\fR \- manages qemu\-toolkit virtual machines
@@ -0,0 +1,34 @@
1
+ module QemuToolkit::Network
2
+ class MacAddress
3
+ def initialize address
4
+ @address = normalize(address)
5
+ end
6
+
7
+ def normalize str
8
+ elements = str.split(':')
9
+
10
+ fail "Malformed MAC address: not enough or too many elements (should == 6, was #{elements.size})." \
11
+ unless elements.size == 6
12
+
13
+ elements.map { |n|
14
+ n.downcase!
15
+ case n.size
16
+ when 1
17
+ '0' + n
18
+ when 2
19
+ n
20
+ else
21
+ fail "Malformed MAC address: #{str}; should have 6 elements with max. 2 digits."
22
+ end
23
+ }.join(':')
24
+ end
25
+
26
+ def == other
27
+ self.to_s == other.to_s
28
+ end
29
+
30
+ def to_s
31
+ @address
32
+ end
33
+ end
34
+ end
@@ -60,6 +60,10 @@ module QemuToolkit
60
60
  attr_accessor :vnc_display
61
61
  # Keyboard layout
62
62
  attr_accessor :keyboard_layout
63
+ # Other devices
64
+ attr_reader :devices
65
+ # Boot order (if set)
66
+ attr_accessor :boot
63
67
 
64
68
  def initialize(backend)
65
69
  @disks = []
@@ -71,8 +75,13 @@ module QemuToolkit
71
75
  @backend = backend
72
76
  @vnc_display = nil
73
77
  @extra_args = []
78
+ # TODO document
79
+ @devices = []
74
80
  end
75
81
 
82
+ def add_device(driver, parameters)
83
+ @devices << [driver, parameters]
84
+ end
76
85
  def add_drive(parameters)
77
86
  @drives << parameters
78
87
  end
@@ -156,29 +165,65 @@ module QemuToolkit
156
165
  cmd << "-vnc #{vnc_display}"
157
166
  end
158
167
 
168
+ # Other devices
169
+ devices.each do |driver, parameters|
170
+ cmd << "-device #{driver}," +
171
+ parameter_list(parameters)
172
+ end
173
+
174
+ # Boot order
175
+ if boot
176
+ cmd << "-boot " + parameter_list(boot)
177
+ end
178
+
179
+ cmd += network_options
180
+
181
+ # Extra arguments
182
+ cmd += @extra_args
183
+
184
+ return cmd
185
+ end
186
+ def network_options
187
+ cmd = []
188
+
159
189
  # networking: nic
160
190
  vlan = 0
161
191
  # Look up all existing vnics for this virtual machine
162
192
  vnics = Vnic.for_prefix(name, @backend)
163
193
 
164
194
  nics.each do |nic_name, parameters|
165
- # All vnics that travel via the given interface (:via)
166
- vnics_for_interface = vnics[parameters[:via]] || []
167
-
168
- # Get a vnic that travels via the given interface.
169
- vnic = vnics_for_interface.shift ||
170
- Vnic.create(name, parameters[:via], @backend)
195
+ via = parameters.delete(:via)
196
+ model = parameters.delete(:model) || 'virtio'
197
+ macaddr = parameters.delete(:macaddr)
198
+
199
+ # All vnics that travel via the given interface (via)
200
+ vnic = vnics.allocate(via, macaddr)
201
+
202
+ # If no vnic has been found, create a new one.
203
+ unless vnic
204
+ vnic = Vnic.create(name, via, @backend, macaddr)
205
+ end
171
206
 
172
207
  cmd << "-net vnic,"+
173
208
  parameter_list(
174
- vlan: vlan, name: nic_name,
175
- ifname: vnic.vnic_name,
176
- macaddr: parameters[:macaddr])
177
- cmd << "-net nic,"+
178
- parameter_list(
179
- vlan: vlan, name: nic_name,
180
- model: parameters[:model] || 'virtio',
181
- macaddr: parameters[:macaddr])
209
+ parameters.merge(
210
+ vlan: vlan, name: nic_name,
211
+ ifname: vnic.vnic_name,
212
+ ))
213
+
214
+ if model == 'virtio'
215
+ cmd << '-device virtio-net-pci,'+
216
+ parameter_list(
217
+ mac: macaddr,
218
+ tx: 'timer', x_txtimer: 200000, x_txburst: 128,
219
+ vlan: vlan)
220
+ else
221
+ cmd << "-net nic,"+
222
+ parameter_list(
223
+ vlan: vlan, name: nic_name,
224
+ model: model,
225
+ macaddr: macaddr)
226
+ end
182
227
 
183
228
  vlan += 1
184
229
  end
@@ -188,11 +233,8 @@ module QemuToolkit
188
233
  cmd << "-net #{type},"+
189
234
  parameter_list(parameters)
190
235
  end
191
-
192
- # Extra arguments
193
- cmd += @extra_args
194
-
195
- return cmd
236
+
237
+ cmd
196
238
  end
197
239
  def disk_options
198
240
  cmd = []
@@ -303,8 +345,13 @@ module QemuToolkit
303
345
  # Formats a parameter list as key=value,key=value
304
346
  #
305
347
  def parameter_list(parameters)
348
+ key_translator = Hash.new { |h,k| k }
349
+ key_translator.update(
350
+ x_txtimer: 'x-txtimer',
351
+ x_txburst: 'x-txburst')
352
+
306
353
  parameters.
307
- map { |k,v| "#{k}=#{v}" }.
354
+ map { |k,v| "#{key_translator[k]}=#{v}" }.
308
355
  join(',')
309
356
  end
310
357
 
@@ -41,10 +41,14 @@ module QemuToolkit
41
41
 
42
42
  subcommand('list',
43
43
  'Lists all virtual machines on this system') do
44
+
45
+ option %w(-o --fields), 'FIELDLIST', "Only outputs fields given; default is all fields (name, pid)"
46
+
44
47
  def _execute
48
+ output_fields = (fields || 'name,pid').split(/,/)
45
49
  VM.all(backend).each do |vm|
46
- printf "%-20s", vm.name
47
- printf " %5s", vm.running? ? vm.pid : 'off'
50
+ printf "%-20s", vm.name if output_fields.include?('name')
51
+ printf " %5s", vm.running? ? vm.pid : 'off' if output_fields.include?('pid')
48
52
  puts
49
53
  end
50
54
  end
@@ -1,57 +1,92 @@
1
+
2
+ require 'set'
3
+
4
+ require 'qemu-toolkit/network/mac_address'
5
+
1
6
  module QemuToolkit
2
7
  class Vnic
3
8
  class << self
4
9
  def for_prefix(prefix, background)
5
- vnics = Hash.new { |h,k| h[k] = Array.new; }
6
- links = background.dladm 'show-vnic', '-po link,over,vid'
10
+ vnics = VnicCollection.new
11
+ links = background.dladm 'show-vnic', '-po link,over,vid,macaddress'
12
+
13
+ re_separator = /(?<!\\):/
7
14
 
8
15
  links.each_line do |line|
9
16
  next unless line.start_with?(prefix)
10
- link, over, vid = line.chomp.split(':')
17
+ link, over, vid, macaddr = line.chomp.split(re_separator)
18
+
19
+ # macaddr being the only place escaping takes place, unescape it
20
+ # by replacing \: -> :
21
+ macaddr.gsub!(/\\:/, ':')
11
22
 
12
23
  # Assumes that vid 0 is always the 'no vlan' VLAN
13
24
  over = "#{over}:#{vid}" if vid.to_i > 0
14
25
 
15
26
  if md=link.match(/^(?<vm>.*)_(?<link_no>\d+)$/)
16
- vnics[over] << Vnic.new(md[:vm], Integer(md[:link_no]), over)
27
+ vnics << Vnic.new(md[:vm], Integer(md[:link_no]), over, macaddr)
17
28
  end
18
29
  end
19
30
 
20
31
  vnics
21
32
  end
22
33
 
23
- def create(prefix, over, backend)
34
+ def create(prefix, over, backend, macaddr=nil)
24
35
  # Retrieve links that exist for this prefix and this over interface
25
- vnics = for_prefix(prefix, backend).values.flatten
36
+ vnics = for_prefix(prefix, backend)
26
37
  next_vnic_number = (vnics.map(&:number).max || 0) + 1
27
38
 
28
- new(prefix, next_vnic_number, over).tap { |o|
39
+ new(prefix, next_vnic_number, over, macaddr).tap { |o|
29
40
  o.create(backend) }
30
41
  end
31
42
 
32
43
  end
33
44
 
34
- def initialize(prefix, number, over)
45
+ def initialize(prefix, number, over, macaddr=nil)
35
46
  @prefix, @number, @over = prefix, number, over
47
+ @macaddr = macaddr && Network::MacAddress.new(macaddr)
48
+
49
+ if vlan_tagged?
50
+ @interface, @vlan = @over.split(':')
51
+ else
52
+ @interface = @over
53
+ @vlan = nil
54
+ end
36
55
  end
37
56
 
38
57
  attr_reader :prefix
39
58
  attr_reader :number
40
59
  attr_reader :over
60
+ attr_reader :macaddr
61
+
62
+ attr_reader :interface
63
+ attr_reader :vlan
41
64
 
42
65
  def ==(other)
43
66
  self.prefix == other.prefix &&
44
67
  self.number == other.number &&
45
- self.over == other.over
68
+ self.over == other.over &&
69
+ self.macaddr == other.macaddr
70
+ end
71
+
72
+ def to_s
73
+ "#{vnic_name} (#{vlan || 'g'}/#{macaddr})"
74
+ end
75
+
76
+ def vlan_tagged?
77
+ @over.index(':')
78
+ end
79
+ def mac_address?
80
+ @macaddr
46
81
  end
47
82
 
48
83
  def create backend
49
- if over.index(':')
50
- iface, vlan = over.split(':')
51
- backend.dladm 'create-vnic', "-l #{iface} -v #{vlan}", vnic_name
52
- else
53
- backend.dladm 'create-vnic', "-l #{over}", vnic_name
54
- end
84
+ opts = ["-l #{interface}"]
85
+
86
+ opts << "-v #{vlan}" if vlan_tagged?
87
+ opts << "--mac-address #{macaddr}" if mac_address?
88
+
89
+ backend.dladm 'create-vnic', *opts, vnic_name
55
90
  end
56
91
 
57
92
  def vnic_name
@@ -0,0 +1,46 @@
1
+
2
+ require 'qemu-toolkit/network/mac_address'
3
+
4
+ module QemuToolkit
5
+
6
+ # A collection of vnics. This class keeps track of vnic allocations to
7
+ # devices, so that no vnic will be used twice.
8
+ #
9
+ class VnicCollection
10
+ def initialize(vnics=[])
11
+ @vnics = Set.new(vnics)
12
+ @used = Set.new
13
+ end
14
+
15
+ def << vnic
16
+ @vnics << vnic
17
+ end
18
+
19
+ def map &block
20
+ unused.map(&block)
21
+ end
22
+
23
+ def unused
24
+ @vnics - @used
25
+ end
26
+
27
+ def allocate(via, mac_address=nil)
28
+ vnic=unused.find { |vnic|
29
+ (!mac_address ||
30
+ (normalize_mac_address(mac_address) == vnic.macaddr)) &&
31
+ via == vnic.over }
32
+
33
+ @used << vnic
34
+ vnic
35
+ end
36
+
37
+ def empty?
38
+ @used.size == @vnics.size
39
+ end
40
+
41
+ def normalize_mac_address mac_address
42
+ Network::MacAddress.new(mac_address)
43
+ end
44
+ end
45
+ end
46
+
data/lib/qemu-toolkit.rb CHANGED
@@ -9,4 +9,5 @@ require 'qemu-toolkit/config'
9
9
  require 'qemu-toolkit/vm'
10
10
  require 'qemu-toolkit/vm_storage'
11
11
  require 'qemu-toolkit/backend/illumos'
12
- require 'qemu-toolkit/vnic'
12
+ require 'qemu-toolkit/vnic'
13
+ require 'qemu-toolkit/vnic_collection'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qemu-toolkit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.5
4
+ version: 0.5.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-23 00:00:00.000000000 Z
12
+ date: 2013-04-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: clamp
@@ -45,11 +45,13 @@ files:
45
45
  - lib/qemu-toolkit/dsl.rb
46
46
  - lib/qemu-toolkit/iscsi_target.rb
47
47
  - lib/qemu-toolkit/local_disk_set.rb
48
+ - lib/qemu-toolkit/network/mac_address.rb
48
49
  - lib/qemu-toolkit/storadm.rb
49
50
  - lib/qemu-toolkit/vm.rb
50
51
  - lib/qemu-toolkit/vm_storage.rb
51
52
  - lib/qemu-toolkit/vmadm.rb
52
53
  - lib/qemu-toolkit/vnic.rb
54
+ - lib/qemu-toolkit/vnic_collection.rb
53
55
  - lib/qemu-toolkit.rb
54
56
  - bin/storadm
55
57
  - bin/vmadm
@@ -95,3 +97,4 @@ signing_key:
95
97
  specification_version: 3
96
98
  summary: Manages QEMU kvm virtual machines on Illumos hosts.
97
99
  test_files: []
100
+ has_rdoc: