vagrant-kvm 0.1.7 → 0.1.8
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/.gitignore +5 -0
- data/CHANGELOG.md +0 -7
- data/DEVELOPMENT.md +69 -0
- data/INSTALL.md +1 -1
- data/README.md +61 -47
- data/bin/package.sh +83 -0
- data/install.rb +7 -0
- data/lib/vagrant-kvm/action.rb +23 -31
- data/lib/vagrant-kvm/action/customize.rb +44 -0
- data/lib/vagrant-kvm/action/import.rb +52 -23
- data/lib/vagrant-kvm/action/init_storage_pool.rb +5 -4
- data/lib/vagrant-kvm/action/network.rb +127 -30
- data/lib/vagrant-kvm/action/{prepare_gui.rb → prepare_kvmconfig.rb} +4 -1
- data/lib/vagrant-kvm/action/prepare_nfs_settings.rb +16 -23
- data/lib/vagrant-kvm/action/set_name.rb +27 -3
- data/lib/vagrant-kvm/action/share_folders.rb +4 -5
- data/lib/vagrant-kvm/cap/mount_p9.rb +40 -0
- data/lib/vagrant-kvm/config.rb +73 -1
- data/lib/vagrant-kvm/driver/driver.rb +303 -117
- data/lib/vagrant-kvm/errors.rb +4 -4
- data/lib/vagrant-kvm/plugin.rb +12 -2
- data/lib/vagrant-kvm/provider.rb +2 -19
- data/lib/vagrant-kvm/synced_folder.rb +57 -0
- data/lib/vagrant-kvm/util/network_definition.rb +30 -3
- data/lib/vagrant-kvm/util/vm_definition.rb +110 -11
- data/lib/vagrant-kvm/version.rb +1 -1
- data/locales/en.yml +5 -3
- data/locales/ja.yml +11 -4
- data/spec/vagrant-kvm/config_spec.rb +6 -0
- data/spec/vagrant-kvm/driver/driver_spec.rb +4 -3
- data/spec/vagrant-kvm/util/vm_definition_spec.rb +4 -8
- data/templates/libvirt_domain.erb +29 -3
- data/vagrant-kvm.gemspec +3 -3
- metadata +21 -9
- data/lib/vagrant-kvm/action/prune_nfs_exports.rb +0 -20
data/lib/vagrant-kvm/errors.rb
CHANGED
@@ -19,10 +19,6 @@ module VagrantPlugins
|
|
19
19
|
error_key(:kvm_no_qemu_binary)
|
20
20
|
end
|
21
21
|
|
22
|
-
class KvmFailImageConversion < VagrantKVMError
|
23
|
-
error_key(:kvm_fail_image_conversion)
|
24
|
-
end
|
25
|
-
|
26
22
|
class KvmBadBoxFormat < VagrantKVMError
|
27
23
|
error_key(:kvm_bad_box_format)
|
28
24
|
end
|
@@ -30,6 +26,10 @@ module VagrantPlugins
|
|
30
26
|
class KvmFailedCommand < VagrantKVMError
|
31
27
|
error_key(:kvm_failed_command)
|
32
28
|
end
|
29
|
+
|
30
|
+
class KvmFailStoragePool < VagrantKVMError
|
31
|
+
error_key(:kvm_fail_storagepool)
|
32
|
+
end
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
data/lib/vagrant-kvm/plugin.rb
CHANGED
@@ -6,8 +6,8 @@ end
|
|
6
6
|
|
7
7
|
# This is a sanity check to make sure no one is attempting to install
|
8
8
|
# this into an early Vagrant version.
|
9
|
-
if Vagrant::VERSION < "1.
|
10
|
-
raise "The Vagrant KVM plugin is only compatible with Vagrant 1.
|
9
|
+
if Vagrant::VERSION < "1.4.0"
|
10
|
+
raise "The Vagrant KVM plugin is only compatible with Vagrant 1.4+"
|
11
11
|
end
|
12
12
|
|
13
13
|
module VagrantPlugins
|
@@ -34,6 +34,16 @@ module VagrantPlugins
|
|
34
34
|
Provider
|
35
35
|
end
|
36
36
|
|
37
|
+
guest_capability("linux", "mount_p9_shared_folder") do
|
38
|
+
require_relative "cap/mount_p9"
|
39
|
+
Cap::MountP9
|
40
|
+
end
|
41
|
+
|
42
|
+
synced_folder("p9", 20) do
|
43
|
+
require_relative "synced_folder"
|
44
|
+
SyncedFolder
|
45
|
+
end
|
46
|
+
|
37
47
|
# This initializes the internationalization strings.
|
38
48
|
def self.setup_i18n
|
39
49
|
I18n.load_path << File.expand_path("locales/en.yml", ProviderKvm.source_root)
|
data/lib/vagrant-kvm/provider.rb
CHANGED
@@ -47,30 +47,13 @@ module VagrantPlugins
|
|
47
47
|
# we return nil.
|
48
48
|
return nil if state == :not_created
|
49
49
|
|
50
|
-
|
50
|
+
ip_addr = @driver.read_machine_ip
|
51
51
|
return {
|
52
|
-
:host =>
|
52
|
+
:host => ip_addr,
|
53
53
|
:port => "22" # XXX should be somewhere in default config
|
54
54
|
}
|
55
55
|
end
|
56
56
|
|
57
|
-
# XXX duplicated from prepare_nfs_settings
|
58
|
-
# Returns the IP address of the guest by looking at the first
|
59
|
-
# enabled host only network.
|
60
|
-
#
|
61
|
-
# @return [String]
|
62
|
-
def read_machine_ip
|
63
|
-
@machine.config.vm.networks.each do |type, options|
|
64
|
-
if type == :private_network && options[:ip].is_a?(String)
|
65
|
-
return options[:ip]
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
# XXX duplicated with network.rb default
|
70
|
-
# If no private network configuration, return default ip
|
71
|
-
"192.168.123.10"
|
72
|
-
end
|
73
|
-
|
74
57
|
# Return the state of the VM
|
75
58
|
#
|
76
59
|
# @return [Symbol]
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module ProviderKvm
|
5
|
+
class SyncedFolder < Vagrant.plugin("2", :synced_folder)
|
6
|
+
def usable?(machine)
|
7
|
+
# These synced folders only work if the provider if KVM
|
8
|
+
machine.provider_name == :kvm
|
9
|
+
end
|
10
|
+
|
11
|
+
def prepare(machine, folders, _opts)
|
12
|
+
defs = []
|
13
|
+
folders.each do |id, data|
|
14
|
+
# access_mode can be squash, mapped, or passthrough
|
15
|
+
accessmode = data.has_key?(:access_mode)? data[:access_mode] : 'squash'
|
16
|
+
accessmode = 'squash' unless accessmode == 'mapped' || accessmode == 'passthrough'
|
17
|
+
# tag maximum len is 31
|
18
|
+
tag = Digest::MD5.new.update(id).to_s[0,31]
|
19
|
+
defs << {
|
20
|
+
:mount_tag => tag,
|
21
|
+
:hostpath => data[:hostpath].to_s,
|
22
|
+
:accessmode => accessmode
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
driver(machine).share_folders(defs)
|
27
|
+
end
|
28
|
+
|
29
|
+
def enable(machine, folders, _opts)
|
30
|
+
# Go through each folder and mount
|
31
|
+
machine.ui.info("mounting p9 share in guest")
|
32
|
+
# Only mount folders that have a guest path specified.
|
33
|
+
mount_folders = {}
|
34
|
+
folders.each do |id, opts|
|
35
|
+
mount_folders[id] = opts.dup if opts[:guestpath]
|
36
|
+
end
|
37
|
+
common_opts = {
|
38
|
+
:version => '9p2000.L',
|
39
|
+
}
|
40
|
+
# Mount the actual folder
|
41
|
+
machine.guest.capability(
|
42
|
+
:mount_p9_shared_folder, mount_folders, common_opts)
|
43
|
+
end
|
44
|
+
|
45
|
+
def cleanup(machine, opts)
|
46
|
+
driver(machine).clear_shared_folders if machine.id && machine.id != ""
|
47
|
+
end
|
48
|
+
|
49
|
+
protected
|
50
|
+
|
51
|
+
# This is here so that we can stub it for tests
|
52
|
+
def driver(machine)
|
53
|
+
machine.provider.driver
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -13,11 +13,11 @@ module VagrantPlugins
|
|
13
13
|
self.attributes = {
|
14
14
|
:forward => "nat",
|
15
15
|
:domain_name => "vagrant.local",
|
16
|
-
:base_ip => "192.168.
|
16
|
+
:base_ip => "192.168.123.1",
|
17
17
|
:netmask => "255.255.255.0",
|
18
18
|
:range => {
|
19
|
-
:start => "192.168.
|
20
|
-
:end => "192.168.
|
19
|
+
:start => "192.168.123.100",
|
20
|
+
:end => "192.168.123.200",
|
21
21
|
},
|
22
22
|
:hosts => [],
|
23
23
|
name: name,
|
@@ -60,6 +60,33 @@ module VagrantPlugins
|
|
60
60
|
def as_xml
|
61
61
|
KvmTemplateRenderer.render("libvirt_network", attributes.dup)
|
62
62
|
end
|
63
|
+
|
64
|
+
# Provide host xml block to update definiton through libvirt(>= 0.5.0)
|
65
|
+
def as_host_xml
|
66
|
+
xml = ""
|
67
|
+
hosts.each do |host|
|
68
|
+
xml = xml + "<host mac='#{host[:mac]}' name='#{host[:name]}' ip='#{host[:ip]}' />"
|
69
|
+
end
|
70
|
+
xml
|
71
|
+
end
|
72
|
+
|
73
|
+
def hosts
|
74
|
+
get(:hosts)
|
75
|
+
end
|
76
|
+
|
77
|
+
def already_exist_host?(config)
|
78
|
+
hosts.each do |host|
|
79
|
+
return true if host[:mac]==config[:mac]
|
80
|
+
end
|
81
|
+
false
|
82
|
+
end
|
83
|
+
|
84
|
+
def already_exist_ip?(config)
|
85
|
+
hosts.each do |host|
|
86
|
+
return true if host[:ip]==config[:ip]
|
87
|
+
end
|
88
|
+
false
|
89
|
+
end
|
63
90
|
end
|
64
91
|
end
|
65
92
|
end
|
@@ -33,11 +33,16 @@ module VagrantPlugins
|
|
33
33
|
:gui => nil,
|
34
34
|
:vnc_autoport => false,
|
35
35
|
:vnc_password => nil,
|
36
|
-
:network => '
|
36
|
+
:network => 'vagrant',
|
37
37
|
:network_model => 'virtio',
|
38
|
-
:video_model => 'cirrus'
|
38
|
+
:video_model => 'cirrus',
|
39
|
+
:secmodel => nil,
|
40
|
+
:sound => nil,
|
41
|
+
:nics => [],
|
39
42
|
}
|
40
43
|
doc = REXML::Document.new definition
|
44
|
+
|
45
|
+
# Basic devices
|
41
46
|
memory_unit = doc.elements["/domain/memory"].attributes["unit"]
|
42
47
|
update({
|
43
48
|
:name => doc.elements["/domain/name"].text,
|
@@ -48,23 +53,41 @@ module VagrantPlugins
|
|
48
53
|
:machine_type => doc.elements["/domain/os/type"].attributes["machine"],
|
49
54
|
:disk => doc.elements["//devices/disk/source"].attributes["file"],
|
50
55
|
:network => doc.elements["//devices/interface/source"].attributes["network"],
|
51
|
-
:
|
52
|
-
:mac => format_mac(doc.elements["//devices/interface/mac"].attributes["address"]),
|
56
|
+
:mac => doc.elements["//devices/interface/mac"].attributes["address"],
|
53
57
|
:image_type => doc.elements["//devices/disk/driver"].attributes["type"],
|
54
58
|
:qemu_bin => doc.elements["/domain/devices/emulator"].text,
|
55
59
|
:video_model => doc.elements["/domain/devices/video/model"].attributes["type"],
|
56
60
|
:disk_bus => doc.elements["//devices/disk/target"].attributes["bus"]
|
57
61
|
})
|
58
|
-
|
59
|
-
|
60
|
-
update({
|
61
|
-
|
62
|
-
|
63
|
-
|
62
|
+
# Security Model
|
63
|
+
doc.elements.each("/domain/seclabel") do |seclabel|
|
64
|
+
update({:secmodel => seclabel.attributes["model"]})
|
65
|
+
end
|
66
|
+
# NETWORK Interfaces
|
67
|
+
nics = []
|
68
|
+
doc.elements.each("//devices/interface") do |intf|
|
69
|
+
network = intf.elements["source"].attributes["network"]
|
70
|
+
mac = intf.elements["mac"].attributes["address"]
|
71
|
+
type = intf.attributes["type"]
|
72
|
+
model = intf.elements["model"].attributes["type"]
|
73
|
+
if network == 'vagrant' then
|
74
|
+
update({:network_model => model})
|
75
|
+
else
|
76
|
+
nics << {
|
77
|
+
:network => network,
|
78
|
+
:mac => format_mac(mac),
|
79
|
+
:type => type,
|
80
|
+
:model => model,
|
81
|
+
# XXX: fixme for supprting bridge
|
82
|
+
}
|
83
|
+
end
|
64
84
|
end
|
85
|
+
update({ :nics => nics })
|
86
|
+
# UUID
|
65
87
|
if doc.elements["/domain/uuid"]
|
66
88
|
update({:uuid => doc.elements["/domain/uuid"].text})
|
67
89
|
end
|
90
|
+
# VNC
|
68
91
|
if doc.elements["//devices/graphics"]
|
69
92
|
attrs = doc.elements["//devices/graphics"].attributes
|
70
93
|
update({
|
@@ -74,6 +97,12 @@ module VagrantPlugins
|
|
74
97
|
:vnc_password => attrs['passwd']
|
75
98
|
})
|
76
99
|
end
|
100
|
+
# SOUND
|
101
|
+
if doc.elements["//devices/sound"]
|
102
|
+
update({
|
103
|
+
:sound => true
|
104
|
+
})
|
105
|
+
end
|
77
106
|
end
|
78
107
|
|
79
108
|
def as_xml
|
@@ -99,7 +128,77 @@ module VagrantPlugins
|
|
99
128
|
attributes.merge!(:memory_size => get_memory("KiB"),
|
100
129
|
:memory_unit => "KiB")
|
101
130
|
)
|
102
|
-
|
131
|
+
# not inject nics to definition when called for export
|
132
|
+
# FIXME: bad design
|
133
|
+
# export call here with (uuid = nil)
|
134
|
+
if get(:uuid)
|
135
|
+
inject_nics(xml)
|
136
|
+
else
|
137
|
+
xml
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# inject nics into XML
|
142
|
+
#
|
143
|
+
# primary NIC is 0000:00:03.0
|
144
|
+
# and injected to 0000:01:01.0 ~ 0000:00:1f.0
|
145
|
+
#
|
146
|
+
def inject_nics(xml)
|
147
|
+
nics=get(:nics)
|
148
|
+
doc = REXML::Document.new xml
|
149
|
+
primary_nic = doc.elements["//interface"]
|
150
|
+
devid = 1
|
151
|
+
nics.each do |nic|
|
152
|
+
next if nic[:mac] == get(:mac)
|
153
|
+
#XXX: support maximum 31 additional NICs
|
154
|
+
# because of a PCI standard limitation.
|
155
|
+
break if devid > 31
|
156
|
+
|
157
|
+
nic[:type] = 'network' unless nic[:type]
|
158
|
+
nic[:model] = 'virtio' unless nic[:model]
|
159
|
+
|
160
|
+
e = REXML::Element.new('interface')
|
161
|
+
e.add_attributes({'type' => nic[:type]})
|
162
|
+
e.add_element('mac', {'address' => nic[:mac]})
|
163
|
+
e.add_element('source', {'network' => nic[:network]})
|
164
|
+
e.add_element('model', {'type' => nic[:model]})
|
165
|
+
e.add_element('address',{'type' => 'pci','domain' => '0x0000',
|
166
|
+
'bus' => '0x01', # bus 0x01 is for NICs, 0x02 is for plan9fs
|
167
|
+
'slot' => '0x%02x'% devid, 'function' => "0"})
|
168
|
+
primary_nic.next_sibling = e
|
169
|
+
devid = devid + 1
|
170
|
+
end
|
171
|
+
doc.to_s
|
172
|
+
end
|
173
|
+
|
174
|
+
# add_nic
|
175
|
+
#
|
176
|
+
# nic
|
177
|
+
# mac: mac address
|
178
|
+
# network: network name(vagrant-*, bridged)
|
179
|
+
# type: network/bridge
|
180
|
+
# model: virtio/ne2k_pci
|
181
|
+
#
|
182
|
+
def add_nic(new_nic)
|
183
|
+
mac = format_mac(new_nic[:mac])
|
184
|
+
nics = get(:nics)
|
185
|
+
unless nics == []
|
186
|
+
# if nic has already exist, update it
|
187
|
+
nics.each_with_index do |nic,i|
|
188
|
+
if nic[:mac] == mac
|
189
|
+
nics[i] = new_nic
|
190
|
+
return set(:nics, nics)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
# add nic to nics
|
195
|
+
nics << {
|
196
|
+
:mac => mac,
|
197
|
+
:network => new_nic[:network],
|
198
|
+
:type => new_nic[:type],
|
199
|
+
:model => new_nic[:model]
|
200
|
+
}
|
201
|
+
set(:nics, nics)
|
103
202
|
end
|
104
203
|
|
105
204
|
def get_memory(unit="bytes")
|
data/lib/vagrant-kvm/version.rb
CHANGED
data/locales/en.yml
CHANGED
@@ -4,19 +4,21 @@ en:
|
|
4
4
|
This is a test message.
|
5
5
|
repair_permission: |-
|
6
6
|
Change directory %{directory} permission from %{old_mode} to %{new_mode}.
|
7
|
+
kvm_spool_problem_inform: |-
|
8
|
+
Your vagrant-kvm environment should be fixed. see README.
|
7
9
|
errors:
|
8
10
|
kvm_no_connection: |-
|
9
11
|
Cannot connect to KVM through Libvirt. Please check kernel module
|
10
12
|
'kvm' and 'kvm-intel' or 'kvm-amd' are installed and your id is in
|
11
|
-
group
|
13
|
+
group libvirtd(in debian/ubuntu).
|
12
14
|
kvm_invalid_version: |-
|
13
15
|
Invalid Kvm version detected: %{actual}, but a version %{required} is
|
14
16
|
required.
|
15
17
|
kvm_no_qemu_binary: |-
|
16
18
|
Executable binary of qemu could not be found. Please re-examine %{cause}.
|
17
|
-
kvm_fail_image_conversion: |-
|
18
|
-
Failed to convert image to specified format.
|
19
19
|
kvm_failed_command: |-
|
20
20
|
System command %{cmd} returned with error code %{res}.
|
21
21
|
kvm_bad_box_format: |-
|
22
22
|
Unsupported box format.
|
23
|
+
kvm_fail_storagepool: |-
|
24
|
+
Failed to activate storage pool.
|
data/locales/ja.yml
CHANGED
@@ -2,13 +2,20 @@ en:
|
|
2
2
|
vagrant_kvm:
|
3
3
|
test_message: |-
|
4
4
|
これはテストメッセージです。
|
5
|
+
kvm_spool_problem_inform: |-
|
6
|
+
このVagrant-kvm環境は修正の必要があります。READMEを確認してください。
|
5
7
|
errors:
|
6
8
|
kvm_no_connection: |-
|
7
9
|
KVMにLibvirt経由で接続できません。カーネルモジュールの
|
8
|
-
|
9
|
-
|
10
|
+
'kvm' 及び、'kvm-intel'か'kvm-amd'が正しくインストールされ、
|
11
|
+
(debian/ubuntuの場合)あなたのユーザIDがlibvirtdグループに属しているか、
|
12
|
+
確認してください。
|
10
13
|
kvm_invalid_version: |-
|
11
|
-
不適切なKVMのバージョンが検出されました:バージョン %{actual}
|
12
|
-
が必要です。
|
14
|
+
不適切なKVMのバージョンが検出されました:バージョン %{actual} が
|
15
|
+
検出されましたが、%{required} が必要です。
|
13
16
|
kvm_no_qemu_binary: |-
|
14
17
|
Qemuの実行バイナリが見つかりません。%{cause}を確認してください。
|
18
|
+
kvm_failed_command: |-
|
19
|
+
システムコマンドの %{cmd} が、エラーコード %{res} を返しました。
|
20
|
+
kvm_bad_box_format: |-
|
21
|
+
サポートされないBOX形式です。
|
@@ -71,6 +71,12 @@ describe VagrantPlugins::ProviderKvm::Config do
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
+
describe "#disk_bus" do
|
75
|
+
it "defaults to nil" do
|
76
|
+
should_default(:disk_bus, nil)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
74
80
|
private
|
75
81
|
def should_default(field, default_value)
|
76
82
|
instance = described_class.new
|
@@ -10,6 +10,7 @@ module VagrantPlugins
|
|
10
10
|
let(:box_path) { test_file "box-disk1.img" }
|
11
11
|
let(:box_pool) { test_file "" }
|
12
12
|
let(:capacity) { {:size=>256, :unit=>'KB'} }
|
13
|
+
let(:pool_path) { '/tmp/pool-storage' }
|
13
14
|
let(:image_path) { '/tmp/pool-storage/box-disk1.img' }
|
14
15
|
let(:image_type) { 'qcow2' }
|
15
16
|
let(:uid) { 1000 }
|
@@ -21,7 +22,6 @@ module VagrantPlugins
|
|
21
22
|
end
|
22
23
|
|
23
24
|
describe "#import" do
|
24
|
-
|
25
25
|
subject do
|
26
26
|
described_class.new(nil)
|
27
27
|
end
|
@@ -34,13 +34,14 @@ module VagrantPlugins
|
|
34
34
|
|
35
35
|
it "does not raise execption" do
|
36
36
|
expect do
|
37
|
-
subject.
|
37
|
+
subject.init_storage_pool("vagrant", pool_path)
|
38
38
|
end.to_not raise_exception
|
39
39
|
end
|
40
40
|
|
41
41
|
it "does not raise exception" do
|
42
42
|
expect do
|
43
|
-
subject.
|
43
|
+
subject.init_storage_pool("vagrant", pool_path)
|
44
|
+
subject.activate_storage_pool("vagrant")
|
44
45
|
subject.create_volume(
|
45
46
|
:disk_name => disk_name,
|
46
47
|
:capacity => capacity,
|