vagrant-libvirt 0.0.15 → 0.0.16
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/CHANGELOG.md +21 -0
- data/Gemfile +4 -0
- data/README.md +34 -23
- data/example_box/Vagrantfile +3 -2
- data/lib/vagrant-libvirt/action.rb +30 -26
- data/lib/vagrant-libvirt/action/connect_libvirt.rb +9 -5
- data/lib/vagrant-libvirt/action/create_domain.rb +47 -3
- data/lib/vagrant-libvirt/action/create_network_interfaces.rb +8 -2
- data/lib/vagrant-libvirt/action/forward_ports.rb +17 -6
- data/lib/vagrant-libvirt/action/prune_nfs_exports.rb +2 -1
- data/lib/vagrant-libvirt/action/read_state.rb +22 -6
- data/lib/vagrant-libvirt/action/set_name_of_domain.rb +7 -1
- data/lib/vagrant-libvirt/cap/mount_p9.rb +40 -0
- data/lib/vagrant-libvirt/cap/synced_folder.rb +103 -0
- data/lib/vagrant-libvirt/config.rb +60 -1
- data/lib/vagrant-libvirt/errors.rb +4 -0
- data/lib/vagrant-libvirt/plugin.rb +14 -2
- data/lib/vagrant-libvirt/templates/domain.xml.erb +11 -0
- data/lib/vagrant-libvirt/templates/filesystem.xml.erb +8 -0
- data/lib/vagrant-libvirt/templates/public_interface.xml.erb +7 -1
- data/lib/vagrant-libvirt/util.rb +1 -0
- data/lib/vagrant-libvirt/util/erb_template.rb +8 -4
- data/lib/vagrant-libvirt/util/error_codes.rb +101 -0
- data/lib/vagrant-libvirt/version.rb +1 -1
- data/locales/en.yml +2 -0
- metadata +7 -5
- data/lib/vagrant-libvirt/action/sync_folders.rb +0 -66
- data/lib/vagrant-libvirt/action/timed_provision.rb +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e5475753167fabd89226aeb3801ae1122a07b0e9
|
4
|
+
data.tar.gz: 4e9db984dfcd0100c10a5e04d7a9b738a64d33ec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bdc9f497e2e357be510406e75e44e6638cdbd4e07830a96821c51cc698ceb21849f2216adfe829bbdc9a96396e46e0507b789b0741f8e996ea3319dbace2a418
|
7
|
+
data.tar.gz: 872af8fbd4e578d78a20f030a04ddf1a9aa60844f0bf6c87603b28b19c2850c5763266a47ec148d106731c15b69a08ddfd46d6a5996b5fe513a212b018e9b58e
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
# 0.0.15 (Feb 01, 2014)
|
2
|
+
* Minimum vagrant version supported is 1.4.3
|
3
|
+
* Add support for port forwarding (by Ryan Petrello <ryan@ryanpetrello.com>)
|
4
|
+
* Improve network device creation (by Brian Pitts <brian@polibyte.com>)
|
5
|
+
* Improvements to NFS sharing (by Matt Palmer and Jason DeTiberus <detiber@gmail.com>)
|
6
|
+
* Provisioning fixes for Vagrant 1.4 (by @keitwb)
|
7
|
+
|
8
|
+
# 0.0.14 (Jan. 21, 2014)
|
9
|
+
* Vagrant 1.4 compatibility fixes (by Dmitry Vasilets <pronix.service@gmail.com>)
|
10
|
+
* Improve how VMs IP address is discovered (by Brian Pitts <brian@polibyte.com>)
|
11
|
+
* Add cpu_mode parameter (by Jordan Tardif <jordan.tardi@gmail.com>)
|
12
|
+
* Add disk_bus parameter (by Brian Pitts <brian@polibyte.com>)
|
13
|
+
* Fixes to some error output (by Matthiew Coudron <matthieu.coudron@lip6.fr>)
|
14
|
+
* Add parameters for booting kernel file (by Matthiew Coudron <matthieu.coudron@lip6.fr>)
|
15
|
+
* Add default_prefix parameter (by James Shubin <purpleidea@gmail.com>)
|
16
|
+
* Improve network creation (by Brian Pitts <brian@polibyte.com>)
|
17
|
+
* Replace default_network parameter with management_network parameters (by Brian Pitts <brian@polibyte.com>)
|
18
|
+
|
19
|
+
# 0.0.13 (Dec. 12, 2013)
|
20
|
+
* Allow to use nested virtualization again (by Artem Chernikov <achernikov@suse.com>)
|
21
|
+
|
1
22
|
# 0.0.12 (Dec. 03, 2013)
|
2
23
|
|
3
24
|
* Proxy ssh through libvirt host, if libvirt is connected via ssh(by @erik-smit)
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -7,9 +7,9 @@ control and provision machines via Libvirt toolkit.
|
|
7
7
|
**Note:** Actual version (0.0.15) is still a development one. Feedback is
|
8
8
|
welcome and can help a lot :-)
|
9
9
|
|
10
|
-
## Features
|
10
|
+
## Features
|
11
11
|
|
12
|
-
*
|
12
|
+
* Control local Libvirt hypervisors.
|
13
13
|
* Vagrant `up`, `destroy`, `suspend`, `resume`, `halt`, `ssh`, `reload` and `provision` commands.
|
14
14
|
* Upload box image (qcow2 format) to Libvirt storage pool.
|
15
15
|
* Create volume as COW diff image for domains.
|
@@ -18,9 +18,10 @@ welcome and can help a lot :-)
|
|
18
18
|
* SSH into domains.
|
19
19
|
* Setup hostname and network interfaces.
|
20
20
|
* Provision domains with any built-in Vagrant provisioner.
|
21
|
-
* Synced folder support via `rsync` or `
|
22
|
-
* Snapshots via [sahara](https://github.com/jedi4ever/sahara)
|
23
|
-
*
|
21
|
+
* Synced folder support via `rsync`, `nfs` or `9p`.
|
22
|
+
* Snapshots via [sahara](https://github.com/jedi4ever/sahara).
|
23
|
+
* Package caching via [vagrant-cachier](http://fgrehm.viewdocs.io/vagrant-cachier/).
|
24
|
+
* Use boxes from other Vagrant providers via [vagrant-mutate](https://github.com/sciurus/vagrant-mutate).
|
24
25
|
|
25
26
|
## Future work
|
26
27
|
|
@@ -79,11 +80,18 @@ Vagrant.configure("2") do |config|
|
|
79
80
|
end
|
80
81
|
|
81
82
|
config.vm.provider :libvirt do |libvirt|
|
82
|
-
libvirt.driver = "
|
83
|
+
libvirt.driver = "kvm"
|
83
84
|
libvirt.host = "localhost"
|
84
85
|
libvirt.connect_via_ssh = true
|
85
86
|
libvirt.username = "root"
|
86
87
|
libvirt.storage_pool_name = "default"
|
88
|
+
|
89
|
+
# include as many of these addition disks as you want to
|
90
|
+
libvirt.storage :file,
|
91
|
+
#:path => '', # automatically chosen if unspecified!
|
92
|
+
#:device => 'vdb', # automatically chosen if unspecified!
|
93
|
+
#:size => '10G', # defaults to 10G if unspecified!
|
94
|
+
:type => 'qcow2' # defaults to 'qcow2' if unspecified!
|
87
95
|
end
|
88
96
|
end
|
89
97
|
```
|
@@ -92,12 +100,13 @@ end
|
|
92
100
|
|
93
101
|
This provider exposes quite a few provider-specific configuration options:
|
94
102
|
|
95
|
-
* `driver` - A hypervisor name to access. For now only qemu
|
103
|
+
* `driver` - A hypervisor name to access. For now only kvm and qemu are supported.
|
96
104
|
* `host` - The name of the server, where libvirtd is running.
|
97
105
|
* `connect_via_ssh` - If use ssh tunnel to connect to Libvirt.
|
98
106
|
* `username` - Username and password to access Libvirt.
|
99
107
|
* `password` - Password to access Libvirt.
|
100
108
|
* `id_ssh_key_file` - The id ssh key file name to access Libvirt (eg: id_dsa or id_rsa or ... in the user .ssh directory)
|
109
|
+
* `socket` - Path to the libvirt unix socket (eg: /var/run/libvirt/libvirt-sock)
|
101
110
|
* `storage_pool_name` - Libvirt storage pool name, where box image and instance snapshots will be stored.
|
102
111
|
|
103
112
|
### Domain Specific Options
|
@@ -108,9 +117,9 @@ This provider exposes quite a few provider-specific configuration options:
|
|
108
117
|
* `nested` - [Enable nested virtualization](https://github.com/torvalds/linux/blob/master/Documentation/virtual/kvm/nested-vmx.txt). Default is false.
|
109
118
|
* `cpu_mode` - What cpu mode to use for nested virtualization. Defaults to 'host-model' if not set.
|
110
119
|
* `volume_cache` - Controls the cache mechanism. Possible values are "default", "none", "writethrough", "writeback", "directsync" and "unsafe". [See driver->cache in libvirt documentation](http://libvirt.org/formatdomain.html#elementsDisks).
|
111
|
-
* `kernel` - To launch the guest with a kernel residing on host filesystems
|
112
|
-
* `initrd` - To specify the initramfs/initrd to use for the guest
|
113
|
-
* `cmd_line` - Arguments passed on to the guest kernel initramfs or initrd to use
|
120
|
+
* `kernel` - To launch the guest with a kernel residing on host filesystems. Equivalent to qemu `-kernel`.
|
121
|
+
* `initrd` - To specify the initramfs/initrd to use for the guest. Equivalent to qemu `-initrd`.
|
122
|
+
* `cmd_line` - Arguments passed on to the guest kernel initramfs or initrd to use. Equivalent to qemu `-append`.
|
114
123
|
|
115
124
|
|
116
125
|
Specific domain settings can be set for each domain separately in multi-VM
|
@@ -156,7 +165,7 @@ Vagrant goes through steps below when creating new project:
|
|
156
165
|
4. Create and start new domain on Libvirt host.
|
157
166
|
5. Check for DHCP lease from dnsmasq server.
|
158
167
|
6. Wait till SSH is available.
|
159
|
-
7. Sync folders
|
168
|
+
7. Sync folders and run Vagrant provisioner on new domain if
|
160
169
|
setup in Vagrantfile.
|
161
170
|
|
162
171
|
## Networks
|
@@ -228,7 +237,7 @@ starts with 'libvirt__' string. Here is a list of those options:
|
|
228
237
|
* `:mac` - MAC address for the interface.
|
229
238
|
|
230
239
|
### Public Network Options
|
231
|
-
* `:dev` - Physical device that the public interface should use. Default is 'eth0'
|
240
|
+
* `:dev` - Physical device that the public interface should use. Default is 'eth0'.
|
232
241
|
* `:mode` - The mode in which the public interface should operate in. Supported
|
233
242
|
modes are available from the [libvirt documentation](http://www.libvirt.org/formatdomain.html#elementsNICSDirect).
|
234
243
|
Default mode is 'bridge'.
|
@@ -279,14 +288,16 @@ will maintain an active ssh process for the lifetime of the VM.
|
|
279
288
|
|
280
289
|
## Synced Folders
|
281
290
|
|
282
|
-
|
283
|
-
|
284
|
-
to the
|
291
|
+
vagrant-libvirt supports bidirectional synced folders via nfs or 9p and
|
292
|
+
unidirectional via rsync. The default is nfs. Vagrant automatically syncs
|
293
|
+
the project folder on the host to */vagrant* in the guest. You can also
|
294
|
+
configure additional synced folders.
|
295
|
+
|
296
|
+
You can change the synced folder type for */vagrant* by explicity configuring
|
297
|
+
it an setting the type, e.g.
|
285
298
|
|
286
|
-
|
287
|
-
chef, and puppet) to work!
|
299
|
+
config.vm.synced_folder './', '/vagrant', type: 'rsync'
|
288
300
|
|
289
|
-
If used options `:nfs => true`, folder will exported by nfs.
|
290
301
|
|
291
302
|
## Box Format
|
292
303
|
|
@@ -335,9 +346,9 @@ IMPORTANT NOTE: bundle is crucial. You need to use bundled vagrant.
|
|
335
346
|
|
336
347
|
## Contributing
|
337
348
|
|
338
|
-
1. Fork it
|
339
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
340
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
341
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
342
|
-
5. Create new Pull Request
|
349
|
+
1. Fork it.
|
350
|
+
2. Create your feature branch (`git checkout -b my-new-feature`).
|
351
|
+
3. Commit your changes (`git commit -am 'Add some feature'`).
|
352
|
+
4. Push to the branch (`git push origin my-new-feature`).
|
353
|
+
5. Create new Pull Request.
|
343
354
|
|
data/example_box/Vagrantfile
CHANGED
@@ -33,10 +33,11 @@ Vagrant.configure("2") do |config|
|
|
33
33
|
|
34
34
|
# A hypervisor name to access. Different drivers can be specified, but
|
35
35
|
# this version of provider creates KVM machines only. Some examples of
|
36
|
-
# drivers are
|
36
|
+
# drivers are kvm (qemu hardware accelerated), qemu (qemu emulated),
|
37
|
+
# xen (Xen hypervisor), lxc (Linux Containers),
|
37
38
|
# esx (VMware ESX), vmwarews (VMware Workstation) and more. Refer to
|
38
39
|
# documentation for available drivers (http://libvirt.org/drivers.html).
|
39
|
-
libvirt.driver = "
|
40
|
+
libvirt.driver = "kvm"
|
40
41
|
|
41
42
|
# The name of the server, where libvirtd is running.
|
42
43
|
libvirt.host = "localhost"
|
@@ -18,32 +18,35 @@ module VagrantPlugins
|
|
18
18
|
if !env[:result]
|
19
19
|
b2.use SetNameOfDomain
|
20
20
|
b2.use HandleStoragePool
|
21
|
-
b2.use
|
21
|
+
b2.use HandleBox
|
22
22
|
b2.use HandleBoxImage
|
23
23
|
b2.use CreateDomainVolume
|
24
24
|
b2.use CreateDomain
|
25
25
|
|
26
|
-
b2.use
|
26
|
+
b2.use Provision
|
27
27
|
b2.use CreateNetworks
|
28
28
|
b2.use CreateNetworkInterfaces
|
29
29
|
|
30
|
+
|
31
|
+
b2.use PrepareNFSValidIds
|
32
|
+
b2.use SyncedFolderCleanup
|
33
|
+
b2.use SyncedFolders
|
34
|
+
|
30
35
|
b2.use StartDomain
|
31
36
|
b2.use WaitTillUp
|
32
37
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
b2.use SyncedFolders
|
39
|
-
end
|
38
|
+
b2.use StartDomain
|
39
|
+
b2.use WaitTillUp
|
40
|
+
|
41
|
+
|
42
|
+
|
40
43
|
|
41
44
|
b2.use ForwardPorts
|
42
45
|
|
43
46
|
b2.use PrepareNFSSettings
|
44
47
|
b2.use ShareFolders
|
45
48
|
b2.use SetHostname
|
46
|
-
b2.use SyncFolders
|
49
|
+
# b2.use SyncFolders
|
47
50
|
else
|
48
51
|
b2.use action_start
|
49
52
|
end
|
@@ -74,6 +77,11 @@ module VagrantPlugins
|
|
74
77
|
# Ensure networks are created and active
|
75
78
|
b3.use CreateNetworks
|
76
79
|
|
80
|
+
b3.use PrepareNFSValidIds
|
81
|
+
b3.use SyncedFolderCleanup
|
82
|
+
b3.use SyncedFolders
|
83
|
+
|
84
|
+
|
77
85
|
# Start it..
|
78
86
|
b3.use StartDomain
|
79
87
|
|
@@ -81,14 +89,6 @@ module VagrantPlugins
|
|
81
89
|
# so wait for dhcp lease and store IP into machines data_dir.
|
82
90
|
b3.use WaitTillUp
|
83
91
|
|
84
|
-
# Handle shared folders
|
85
|
-
if Vagrant::VERSION < "1.4.0"
|
86
|
-
b3.use NFS
|
87
|
-
else
|
88
|
-
b3.use PrepareNFSValidIds
|
89
|
-
b3.use SyncedFolderCleanup
|
90
|
-
b3.use SyncedFolders
|
91
|
-
end
|
92
92
|
|
93
93
|
b3.use ForwardPorts
|
94
94
|
b3.use PrepareNFSSettings
|
@@ -156,7 +156,7 @@ module VagrantPlugins
|
|
156
156
|
|
157
157
|
b2.use ConnectLibvirt
|
158
158
|
b2.use ClearForwardedPorts
|
159
|
-
b2.use PruneNFSExports
|
159
|
+
# b2.use PruneNFSExports
|
160
160
|
b2.use DestroyDomain
|
161
161
|
b2.use DestroyNetworks
|
162
162
|
end
|
@@ -204,7 +204,7 @@ module VagrantPlugins
|
|
204
204
|
end
|
205
205
|
|
206
206
|
b3.use Provision
|
207
|
-
b3.use SyncFolders
|
207
|
+
# b3.use SyncFolders
|
208
208
|
end
|
209
209
|
end
|
210
210
|
end
|
@@ -321,25 +321,29 @@ module VagrantPlugins
|
|
321
321
|
autoload :MessageNotCreated, action_root.join('message_not_created')
|
322
322
|
autoload :MessageNotRunning, action_root.join('message_not_running')
|
323
323
|
autoload :MessageNotSuspended, action_root.join('message_not_suspended')
|
324
|
+
|
324
325
|
autoload :PrepareNFSSettings, action_root.join('prepare_nfs_settings')
|
325
326
|
autoload :PrepareNFSValidIds, action_root.join('prepare_nfs_valid_ids')
|
326
327
|
autoload :PruneNFSExports, action_root.join('prune_nfs_exports')
|
328
|
+
|
327
329
|
autoload :ReadSSHInfo, action_root.join('read_ssh_info')
|
328
330
|
autoload :ReadState, action_root.join('read_state')
|
329
331
|
autoload :ResumeDomain, action_root.join('resume_domain')
|
330
332
|
autoload :SetNameOfDomain, action_root.join('set_name_of_domain')
|
333
|
+
|
334
|
+
# I don't think we need it anymore
|
331
335
|
autoload :ShareFolders, action_root.join('share_folders')
|
332
336
|
autoload :StartDomain, action_root.join('start_domain')
|
333
337
|
autoload :SuspendDomain, action_root.join('suspend_domain')
|
334
|
-
autoload :SyncFolders, action_root.join('sync_folders')
|
335
338
|
autoload :TimedProvision, action_root.join('timed_provision')
|
339
|
+
|
336
340
|
autoload :WaitTillUp, action_root.join('wait_till_up')
|
341
|
+
autoload :PrepareNFSValidIds, action_root.join('prepare_nfs_valid_ids')
|
342
|
+
|
337
343
|
autoload :SSHRun, 'vagrant/action/builtin/ssh_run'
|
338
|
-
autoload :
|
339
|
-
|
340
|
-
|
341
|
-
autoload :SyncedFolderCleanup, 'vagrant/action/builtin/synced_folder_cleanup'
|
342
|
-
end
|
344
|
+
autoload :HandleBox, 'vagrant/action/builtin/handle_box'
|
345
|
+
autoload :SyncedFolders, 'vagrant/action/builtin/synced_folders'
|
346
|
+
autoload :SyncedFolderCleanup, 'vagrant/action/builtin/synced_folder_cleanup'
|
343
347
|
end
|
344
348
|
end
|
345
349
|
end
|
@@ -23,9 +23,9 @@ module VagrantPlugins
|
|
23
23
|
config = env[:machine].provider_config
|
24
24
|
|
25
25
|
# Setup connection uri.
|
26
|
-
uri = config.driver
|
26
|
+
uri = config.driver.dup
|
27
27
|
virt_path = case uri
|
28
|
-
when 'qemu', 'openvz', 'uml', 'phyp', 'parallels'
|
28
|
+
when 'qemu', 'openvz', 'uml', 'phyp', 'parallels', 'kvm'
|
29
29
|
'/system'
|
30
30
|
when 'xen', 'esx'
|
31
31
|
'/'
|
@@ -34,6 +34,9 @@ module VagrantPlugins
|
|
34
34
|
else
|
35
35
|
raise "Require specify driver #{uri}"
|
36
36
|
end
|
37
|
+
if uri == 'kvm'
|
38
|
+
uri = 'qemu' # use qemu uri for kvm domain type
|
39
|
+
end
|
37
40
|
|
38
41
|
if config.connect_via_ssh
|
39
42
|
uri << '+ssh://'
|
@@ -57,8 +60,10 @@ module VagrantPlugins
|
|
57
60
|
if config.id_ssh_key_file
|
58
61
|
# set ssh key for access to libvirt host
|
59
62
|
home_dir = `echo ${HOME}`.chomp
|
60
|
-
uri << "
|
63
|
+
uri << "\&keyfile=#{home_dir}/.ssh/"+config.id_ssh_key_file
|
61
64
|
end
|
65
|
+
# set path to libvirt socket
|
66
|
+
uri << "\&socket="+config.socket if config.socket
|
62
67
|
|
63
68
|
conn_attr = {}
|
64
69
|
conn_attr[:provider] = 'libvirt'
|
@@ -68,8 +73,7 @@ module VagrantPlugins
|
|
68
73
|
|
69
74
|
# Setup command for retrieving IP address for newly created machine
|
70
75
|
# with some MAC address. Get it from dnsmasq leases table
|
71
|
-
ip_command =
|
72
|
-
ip_command << %q[ [ -n "$LEASES" ] && grep $mac $LEASES | awk '{ print $3 }' ]
|
76
|
+
ip_command = %q[ find /var/lib/libvirt/dnsmasq/ /var/lib/misc/ -name '*leases' -exec grep $mac {} \; | cut -d' ' -f3 ]
|
73
77
|
conn_attr[:libvirt_ip_command] = ip_command
|
74
78
|
|
75
79
|
@logger.info("Connecting to Libvirt (#{uri}) ...")
|
@@ -12,6 +12,14 @@ module VagrantPlugins
|
|
12
12
|
@app = app
|
13
13
|
end
|
14
14
|
|
15
|
+
def _disk_name(name, disk)
|
16
|
+
return "#{name}-#{disk[:device]}.#{disk[:type]}" # disk name
|
17
|
+
end
|
18
|
+
|
19
|
+
def _disks_print(disks)
|
20
|
+
return disks.collect{ |x| x[:device]+'('+x[:type]+','+x[:size]+')' }.join(', ')
|
21
|
+
end
|
22
|
+
|
15
23
|
def call(env)
|
16
24
|
# Get config.
|
17
25
|
config = env[:machine].provider_config
|
@@ -28,8 +36,12 @@ module VagrantPlugins
|
|
28
36
|
@cmd_line = config.cmd_line
|
29
37
|
@initrd = config.initrd
|
30
38
|
|
31
|
-
#
|
32
|
-
@
|
39
|
+
# Storage
|
40
|
+
@storage_pool_name = config.storage_pool_name
|
41
|
+
@disks = config.disks
|
42
|
+
|
43
|
+
config = env[:machine].provider_config
|
44
|
+
@domain_type = config.driver
|
33
45
|
|
34
46
|
@os_type = 'hvm'
|
35
47
|
|
@@ -39,6 +51,32 @@ module VagrantPlugins
|
|
39
51
|
raise Errors::DomainVolumeExists if domain_volume == nil
|
40
52
|
@domain_volume_path = domain_volume.path
|
41
53
|
|
54
|
+
# the default storage prefix is typically: /var/lib/libvirt/images/
|
55
|
+
storage_prefix = File.dirname(@domain_volume_path)+'/' # steal
|
56
|
+
|
57
|
+
@disks.each do |disk|
|
58
|
+
disk[:name] = _disk_name(@name, disk)
|
59
|
+
if disk[:path].nil?
|
60
|
+
disk[:path] = "#{storage_prefix}#{_disk_name(@name, disk)}" # automatically chosen!
|
61
|
+
end
|
62
|
+
|
63
|
+
# make the disk. equivalent to:
|
64
|
+
# qemu-img create -f qcow2 <path> 5g
|
65
|
+
begin
|
66
|
+
#puts "Making disk: #{d}, #{t}, #{p}"
|
67
|
+
domain_volume_disk = env[:libvirt_compute].volumes.create(
|
68
|
+
:name => disk[:name],
|
69
|
+
:format_type => disk[:type],
|
70
|
+
:path => disk[:path],
|
71
|
+
:capacity => disk[:size],
|
72
|
+
#:allocation => ?,
|
73
|
+
:pool_name => @storage_pool_name)
|
74
|
+
rescue Fog::Errors::Error => e
|
75
|
+
raise Errors::FogDomainVolumeCreateError,
|
76
|
+
:error_message => e.message
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
42
80
|
# Output the settings we're going to use to the user
|
43
81
|
env[:ui].info(I18n.t("vagrant_libvirt.creating_domain"))
|
44
82
|
env[:ui].info(" -- Name: #{@name}")
|
@@ -46,11 +84,17 @@ module VagrantPlugins
|
|
46
84
|
env[:ui].info(" -- Cpus: #{@cpus}")
|
47
85
|
env[:ui].info(" -- Memory: #{@memory_size/1024}M")
|
48
86
|
env[:ui].info(" -- Base box: #{env[:machine].box.name}")
|
49
|
-
env[:ui].info(" -- Storage pool: #{
|
87
|
+
env[:ui].info(" -- Storage pool: #{@storage_pool_name}")
|
50
88
|
env[:ui].info(" -- Image: #{@domain_volume_path}")
|
51
89
|
env[:ui].info(" -- Volume Cache: #{@domain_volume_cache}")
|
52
90
|
env[:ui].info(" -- Kernel: #{@kernel}")
|
53
91
|
env[:ui].info(" -- Initrd: #{@initrd}")
|
92
|
+
if @disks.length > 0
|
93
|
+
env[:ui].info(" -- Disks: #{_disks_print(@disks)}")
|
94
|
+
end
|
95
|
+
@disks.each do |disk|
|
96
|
+
env[:ui].info(" -- Disk(#{disk[:device]}): #{disk[:path]}")
|
97
|
+
end
|
54
98
|
env[:ui].info(" -- Command line : #{@cmd_line}")
|
55
99
|
|
56
100
|
# Create libvirt domain.
|
@@ -70,9 +70,11 @@ module VagrantPlugins
|
|
70
70
|
|
71
71
|
# Configuration for public interfaces which use the macvtap driver
|
72
72
|
if iface_configuration[:iface_type] == :public_network
|
73
|
-
template_name = 'public_interface'
|
74
73
|
@device = iface_configuration.fetch(:dev, 'eth0')
|
74
|
+
@type = iface_configuration.fetch(:type, 'direct')
|
75
75
|
@mode = iface_configuration.fetch(:mode, 'bridge')
|
76
|
+
@model_type = iface_configuration.fetch(:model_type, 'e1000')
|
77
|
+
template_name = 'public_interface'
|
76
78
|
@logger.info("Setting up public interface using device #{@device} in mode #{@mode}")
|
77
79
|
end
|
78
80
|
|
@@ -147,6 +149,10 @@ module VagrantPlugins
|
|
147
149
|
# Get list of all (active and inactive) libvirt networks.
|
148
150
|
available_networks = libvirt_networks(libvirt_client)
|
149
151
|
|
152
|
+
if options[:iface_type] == :public_network
|
153
|
+
return 'public'
|
154
|
+
end
|
155
|
+
|
150
156
|
if options[:ip]
|
151
157
|
address = network_address(options[:ip], options[:netmask])
|
152
158
|
available_networks.each do |network|
|
@@ -157,7 +163,7 @@ module VagrantPlugins
|
|
157
163
|
end
|
158
164
|
end
|
159
165
|
|
160
|
-
raise NetworkNotAvailableError, network_name: options[:ip]
|
166
|
+
raise Errors::NetworkNotAvailableError, network_name: options[:ip]
|
161
167
|
end
|
162
168
|
end
|
163
169
|
end
|
@@ -47,8 +47,8 @@ module VagrantPlugins
|
|
47
47
|
))
|
48
48
|
|
49
49
|
ssh_pid = redirect_port(
|
50
|
-
@env[:machine]
|
51
|
-
fp[:host_ip] || '
|
50
|
+
@env[:machine],
|
51
|
+
fp[:host_ip] || 'localhost',
|
52
52
|
fp[:host],
|
53
53
|
fp[:guest_ip] || @env[:machine].provider.ssh_info[:host],
|
54
54
|
fp[:guest]
|
@@ -77,13 +77,24 @@ module VagrantPlugins
|
|
77
77
|
end
|
78
78
|
|
79
79
|
def redirect_port(machine, host_ip, host_port, guest_ip, guest_port)
|
80
|
+
ssh_info = machine.ssh_info
|
80
81
|
params = %W(
|
81
|
-
#{
|
82
|
-
-L #{host_ip}:#{host_port}:#{guest_ip}:#{guest_port}
|
82
|
+
"-L #{host_ip}:#{host_port}:#{guest_ip}:#{guest_port}"
|
83
83
|
-N
|
84
|
+
#{ssh_info[:host]}
|
84
85
|
).join(' ')
|
85
|
-
|
86
|
-
options =
|
86
|
+
|
87
|
+
options = (%W(
|
88
|
+
User=#{ssh_info[:username]}
|
89
|
+
Port=#{ssh_info[:port]}
|
90
|
+
UserKnownHostsFile=/dev/null
|
91
|
+
StrictHostKeyChecking=no
|
92
|
+
PasswordAuthentication=no
|
93
|
+
ForwardX11=#{ssh_info[:forward_x11] ? 'yes' : 'no'}
|
94
|
+
) + ssh_info[:private_key_path].map do |pk|
|
95
|
+
"IdentityFile=#{pk}"
|
96
|
+
end).map { |s| s.prepend('-o ') }.join(' ')
|
97
|
+
|
87
98
|
ssh_cmd = "ssh #{options} #{params}"
|
88
99
|
|
89
100
|
@logger.debug "Forwarding port with `#{ssh_cmd}`"
|
@@ -15,7 +15,8 @@ module VagrantPlugins
|
|
15
15
|
uuids = env[:libvirt_compute].servers.all.map(&:id)
|
16
16
|
# not exiisted in array will removed from nfs
|
17
17
|
uuids.delete(uuid)
|
18
|
-
env[:host].
|
18
|
+
env[:host].capability(
|
19
|
+
:nfs_prune, env[:machine].ui, uuids)
|
19
20
|
end
|
20
21
|
|
21
22
|
@app.call(env)
|
@@ -19,13 +19,29 @@ module VagrantPlugins
|
|
19
19
|
def read_state(libvirt, machine)
|
20
20
|
return :not_created if machine.id.nil?
|
21
21
|
|
22
|
+
begin
|
23
|
+
server = libvirt.servers.get(machine.id)
|
24
|
+
rescue Libvirt::RetrieveError => e
|
25
|
+
server = nil
|
26
|
+
@logger.debug('Machine not found #{e}.')
|
27
|
+
end
|
22
28
|
# Find the machine
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
+
begin
|
30
|
+
server = libvirt.servers.get(machine.id)
|
31
|
+
if server.nil? || [:'shutting-down', :terminated].include?(server.state.to_sym)
|
32
|
+
# The machine can't be found
|
33
|
+
@logger.info('Machine shutting down or terminated, assuming it got destroyed.')
|
34
|
+
machine.id = nil
|
35
|
+
return :not_created
|
36
|
+
end
|
37
|
+
rescue Libvirt::RetrieveError => e
|
38
|
+
if e.libvirt_code == ProviderLibvirt::Util::ErrorCodes::VIR_ERR_NO_DOMAIN
|
39
|
+
@logger.info("Machine #{machine.id} not found.")
|
40
|
+
machine.id = nil
|
41
|
+
return :not_created
|
42
|
+
else
|
43
|
+
raise e
|
44
|
+
end
|
29
45
|
end
|
30
46
|
|
31
47
|
# Return the state
|
@@ -21,10 +21,16 @@ module VagrantPlugins
|
|
21
21
|
env[:domain_name] << '_'
|
22
22
|
env[:domain_name] << env[:machine].name.to_s
|
23
23
|
|
24
|
+
begin
|
24
25
|
@logger.info("Looking for domain #{env[:domain_name]} through list #{env[:libvirt_compute].servers.all}")
|
25
26
|
# Check if the domain name is not already taken
|
26
|
-
|
27
|
+
|
28
|
+
domain = ProviderLibvirt::Util::Collection.find_matching(
|
27
29
|
env[:libvirt_compute].servers.all, env[:domain_name])
|
30
|
+
rescue Fog::Errors::Error => e
|
31
|
+
@logger.info("#{e}")
|
32
|
+
domain = nil
|
33
|
+
end
|
28
34
|
|
29
35
|
@logger.info("Looking for domain #{env[:domain_name]}")
|
30
36
|
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require "vagrant/util/retryable"
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module ProviderLibvirt
|
5
|
+
module Cap
|
6
|
+
class MountP9
|
7
|
+
extend Vagrant::Util::Retryable
|
8
|
+
|
9
|
+
def self.mount_p9_shared_folder(machine, folders, options)
|
10
|
+
folders.each do |name, opts|
|
11
|
+
# Expand the guest path so we can handle things like "~/vagrant"
|
12
|
+
expanded_guest_path = machine.guest.capability(
|
13
|
+
:shell_expand_guest_path, opts[:guestpath])
|
14
|
+
|
15
|
+
# Do the actual creating and mounting
|
16
|
+
machine.communicate.sudo("mkdir -p #{expanded_guest_path}")
|
17
|
+
|
18
|
+
# Mount
|
19
|
+
mount_tag = name.dup
|
20
|
+
|
21
|
+
mount_opts="-o trans=virtio"
|
22
|
+
mount_opts += ",access=#{options[:owner]}" if options[:owner]
|
23
|
+
mount_opts += ",version=#{options[:version]}" if options[:version]
|
24
|
+
mount_opts += ",#{opts[:mount_options]}" if opts[:mount_options]
|
25
|
+
|
26
|
+
mount_command = "mount -t 9p #{mount_opts} '#{mount_tag}' #{expanded_guest_path}"
|
27
|
+
retryable(:on => Vagrant::Errors::LinuxMountFailed,
|
28
|
+
:tries => 5,
|
29
|
+
:sleep => 3) do
|
30
|
+
machine.communicate.sudo('modprobe 9p')
|
31
|
+
machine.communicate.sudo('modprobe 9pnet_virtio')
|
32
|
+
machine.communicate.sudo(mount_command,
|
33
|
+
:error_class => Vagrant::Errors::LinuxMountFailed)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require "log4r"
|
2
|
+
require 'ostruct'
|
3
|
+
require 'nokogiri'
|
4
|
+
|
5
|
+
|
6
|
+
require "vagrant/util/subprocess"
|
7
|
+
require "vagrant/errors"
|
8
|
+
require "vagrant-libvirt/errors"
|
9
|
+
# require_relative "helper"
|
10
|
+
|
11
|
+
module VagrantPlugins
|
12
|
+
module SyncedFolder9p
|
13
|
+
class SyncedFolder < Vagrant.plugin("2", :synced_folder)
|
14
|
+
include Vagrant::Util
|
15
|
+
include VagrantPlugins::ProviderLibvirt::Util::ErbTemplate
|
16
|
+
|
17
|
+
def initialize(*args)
|
18
|
+
super
|
19
|
+
|
20
|
+
@logger = Log4r::Logger.new("vagrant_libvirt::synced_folders::9p")
|
21
|
+
end
|
22
|
+
|
23
|
+
def usable?(machine, raise_error=false)
|
24
|
+
# bail now if not using libvirt since checking version would throw error
|
25
|
+
return false unless machine.provider_name == :libvirt
|
26
|
+
|
27
|
+
# <filesystem/> support in device attach/detach introduced in 1.2.2
|
28
|
+
# version number format is major * 1,000,000 + minor * 1,000 + release
|
29
|
+
libvirt_version = ProviderLibvirt.libvirt_connection.client.libversion
|
30
|
+
if libvirt_version >= 1002002
|
31
|
+
return true
|
32
|
+
else
|
33
|
+
return false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def prepare(machine, folders, opts)
|
38
|
+
|
39
|
+
raise Vagrant::Errors::Error("No libvirt connection") if ProviderLibvirt.libvirt_connection.nil?
|
40
|
+
|
41
|
+
@conn = ProviderLibvirt.libvirt_connection.client
|
42
|
+
|
43
|
+
begin
|
44
|
+
# loop through folders
|
45
|
+
folders.each do |id, folder_opts|
|
46
|
+
folder_opts.merge!({ :accessmode => "passthrough",
|
47
|
+
:readonly => nil })
|
48
|
+
machine.ui.info "================\nMachine id: #{machine.id}\nShould be mounting folders\n #{id}, opts: #{folder_opts}"
|
49
|
+
|
50
|
+
xml = to_xml('filesystem', folder_opts )
|
51
|
+
# puts "<<<<< XML:\n #{xml}\n >>>>>"
|
52
|
+
@conn.lookup_domain_by_uuid(machine.id).attach_device(xml, 0)
|
53
|
+
|
54
|
+
end
|
55
|
+
rescue => e
|
56
|
+
machine.ui.error("could not attach device because: #{e}")
|
57
|
+
raise VagrantPlugins::ProviderLibvirt::Errors::AttachDeviceError,:error_message => e.message
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
# TODO once up, mount folders
|
63
|
+
def enable(machine, folders, _opts)
|
64
|
+
# Go through each folder and mount
|
65
|
+
machine.ui.info("mounting p9 share in guest")
|
66
|
+
# Only mount folders that have a guest path specified.
|
67
|
+
mount_folders = {}
|
68
|
+
folders.each do |id, opts|
|
69
|
+
mount_folders[id] = opts.dup if opts[:guestpath]
|
70
|
+
end
|
71
|
+
common_opts = {
|
72
|
+
:version => '9p2000.L',
|
73
|
+
}
|
74
|
+
# Mount the actual folder
|
75
|
+
machine.guest.capability(
|
76
|
+
:mount_p9_shared_folder, mount_folders, common_opts)
|
77
|
+
end
|
78
|
+
|
79
|
+
def cleanup(machine, _opts)
|
80
|
+
|
81
|
+
raise Vagrant::Errors::Error("No libvirt connection") if ProviderLibvirt.libvirt_connection.nil?
|
82
|
+
|
83
|
+
@conn = ProviderLibvirt.libvirt_connection.client
|
84
|
+
|
85
|
+
begin
|
86
|
+
if machine.id && machine.id != ""
|
87
|
+
dom = @conn.lookup_domain_by_uuid(machine.id)
|
88
|
+
Nokogiri::XML(dom.xml_desc).xpath('/domain/devices/filesystem').each do |xml|
|
89
|
+
dom.detach_device(xml.to_s)
|
90
|
+
|
91
|
+
machine.ui.info "Cleaned up shared folders"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
rescue => e
|
95
|
+
machine.ui.error("could not detach device because: #{e}")
|
96
|
+
raise VagrantPlugins::ProviderLibvirt::Errors::DetachDeviceError,:error_message => e.message
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -1,5 +1,14 @@
|
|
1
1
|
require 'vagrant'
|
2
2
|
|
3
|
+
class Numeric
|
4
|
+
Alphabet = ('a'..'z').to_a
|
5
|
+
def vdev
|
6
|
+
s, q = '', self
|
7
|
+
(q, r = (q - 1).divmod(26)) && s.prepend(Alphabet[r]) until q.zero?
|
8
|
+
'vd'+s
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
3
12
|
module VagrantPlugins
|
4
13
|
module ProviderLibvirt
|
5
14
|
class Config < Vagrant.plugin('2', :config)
|
@@ -12,6 +21,9 @@ module VagrantPlugins
|
|
12
21
|
# If use ssh tunnel to connect to Libvirt.
|
13
22
|
attr_accessor :connect_via_ssh
|
14
23
|
|
24
|
+
# Path towards the libvirt socket
|
25
|
+
attr_accessor :socket
|
26
|
+
|
15
27
|
# The username to access Libvirt.
|
16
28
|
attr_accessor :username
|
17
29
|
|
@@ -43,6 +55,9 @@ module VagrantPlugins
|
|
43
55
|
attr_accessor :cmd_line
|
44
56
|
attr_accessor :initrd
|
45
57
|
|
58
|
+
# Storage
|
59
|
+
attr_accessor :disks
|
60
|
+
|
46
61
|
def initialize
|
47
62
|
@driver = UNSET_VALUE
|
48
63
|
@host = UNSET_VALUE
|
@@ -64,10 +79,51 @@ module VagrantPlugins
|
|
64
79
|
@kernel = UNSET_VALUE
|
65
80
|
@initrd = UNSET_VALUE
|
66
81
|
@cmd_line = UNSET_VALUE
|
82
|
+
|
83
|
+
# Storage
|
84
|
+
@disks = UNSET_VALUE
|
85
|
+
end
|
86
|
+
|
87
|
+
def _get_device(disks)
|
88
|
+
disks = [] if disks == UNSET_VALUE
|
89
|
+
# skip existing devices and also the first one (vda)
|
90
|
+
exist = disks.collect {|x| x[:device]}+[1.vdev.to_s]
|
91
|
+
skip = 1 # we're 1 based, not 0 based...
|
92
|
+
while true do
|
93
|
+
dev = skip.vdev # get lettered device
|
94
|
+
if !exist.include?(dev)
|
95
|
+
return dev
|
96
|
+
end
|
97
|
+
skip+=1
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# NOTE: this will run twice for each time it's needed- keep it idempotent
|
102
|
+
def storage(storage_type, options={})
|
103
|
+
options = {
|
104
|
+
:device => _get_device(@disks),
|
105
|
+
:type => 'qcow2',
|
106
|
+
:size => '10G', # matches the fog default
|
107
|
+
:path => nil,
|
108
|
+
}.merge(options)
|
109
|
+
|
110
|
+
#puts "storage(#{storage_type} --- #{options.to_s})"
|
111
|
+
@disks = [] if @disks == UNSET_VALUE
|
112
|
+
|
113
|
+
disk = {
|
114
|
+
:device => options[:device],
|
115
|
+
:type => options[:type],
|
116
|
+
:size => options[:size],
|
117
|
+
:path => options[:path],
|
118
|
+
}
|
119
|
+
|
120
|
+
if storage_type == :file
|
121
|
+
@disks << disk # append
|
122
|
+
end
|
67
123
|
end
|
68
124
|
|
69
125
|
def finalize!
|
70
|
-
@driver = '
|
126
|
+
@driver = 'kvm' if @driver == UNSET_VALUE
|
71
127
|
@host = nil if @host == UNSET_VALUE
|
72
128
|
@connect_via_ssh = false if @connect_via_ssh == UNSET_VALUE
|
73
129
|
@username = nil if @username == UNSET_VALUE
|
@@ -87,6 +143,9 @@ module VagrantPlugins
|
|
87
143
|
@kernel = nil if @kernel == UNSET_VALUE
|
88
144
|
@cmd_line = '' if @cmd_line == UNSET_VALUE
|
89
145
|
@initrd = '' if @initrd == UNSET_VALUE
|
146
|
+
|
147
|
+
# Storage
|
148
|
+
@disks = [] if @disks == UNSET_VALUE
|
90
149
|
end
|
91
150
|
|
92
151
|
def validate(machine)
|
@@ -122,6 +122,10 @@ module VagrantPlugins
|
|
122
122
|
error_key(:attach_device_error)
|
123
123
|
end
|
124
124
|
|
125
|
+
class DetachDeviceError < VagrantLibvirtError
|
126
|
+
error_key(:detach_device_error)
|
127
|
+
end
|
128
|
+
|
125
129
|
class NoIpAddressError < VagrantLibvirtError
|
126
130
|
error_key(:no_ip_address_error)
|
127
131
|
end
|
@@ -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 Libvirt plugin is only compatible with Vagrant 1.
|
9
|
+
if Vagrant::VERSION < '1.5.0'
|
10
|
+
raise 'The Vagrant Libvirt plugin is only compatible with Vagrant 1.5+'
|
11
11
|
end
|
12
12
|
|
13
13
|
module VagrantPlugins
|
@@ -31,6 +31,18 @@ module VagrantPlugins
|
|
31
31
|
require_relative 'provider'
|
32
32
|
Provider
|
33
33
|
end
|
34
|
+
|
35
|
+
guest_capability("linux", "mount_p9_shared_folder") do
|
36
|
+
require_relative "cap/mount_p9"
|
37
|
+
Cap::MountP9
|
38
|
+
end
|
39
|
+
|
40
|
+
# lower priority than nfs or rsync
|
41
|
+
# https://github.com/pradels/vagrant-libvirt/pull/170
|
42
|
+
synced_folder("9p", 4) do
|
43
|
+
require_relative "cap/synced_folder"
|
44
|
+
VagrantPlugins::SyncedFolder9p::SyncedFolder
|
45
|
+
end
|
34
46
|
|
35
47
|
# This initializes the internationalization strings.
|
36
48
|
def self.setup_i18n
|
@@ -31,6 +31,17 @@
|
|
31
31
|
<%# we need to ensure a unique target dev -%>
|
32
32
|
<target dev='vda' bus='<%= @disk_bus %>'/>
|
33
33
|
</disk>
|
34
|
+
<%# additional disks -%>
|
35
|
+
<% @disks.each do |d| -%>
|
36
|
+
<disk type='file' device='disk'>
|
37
|
+
<driver name='qemu' type='<%= d[:type] %>'/>
|
38
|
+
<source file='<%= d[:path] %>'/>
|
39
|
+
<target dev='<%= d[:device] %>' bus='virtio'/>
|
40
|
+
<%# this will get auto generated by libvirt
|
41
|
+
<address type='pci' domain='0x0000' bus='0x00' slot='???' function='0x0'/>
|
42
|
+
-%>
|
43
|
+
</disk>
|
44
|
+
<% end -%>
|
34
45
|
<serial type='pty'>
|
35
46
|
<target port='0'/>
|
36
47
|
</serial>
|
@@ -1,7 +1,13 @@
|
|
1
|
-
<interface type='
|
1
|
+
<interface type='<%= @type %>'>
|
2
2
|
<% if @mac %>
|
3
3
|
<mac address='<%= @mac %>'/>
|
4
4
|
<% end %>
|
5
|
+
<%if @type == 'direct'%>
|
5
6
|
<source dev='<%= @device %>' mode='<%= @mode %>'/>
|
7
|
+
<% else %>
|
8
|
+
<source bridge='<%=@device%>'/>
|
9
|
+
<model type='<%=@model_type%>'/>
|
10
|
+
<% end %>
|
6
11
|
</interface>
|
7
12
|
|
13
|
+
|
data/lib/vagrant-libvirt/util.rb
CHANGED
@@ -1,17 +1,21 @@
|
|
1
|
-
require '
|
1
|
+
require 'erubis'
|
2
2
|
|
3
3
|
module VagrantPlugins
|
4
4
|
module ProviderLibvirt
|
5
5
|
module Util
|
6
6
|
module ErbTemplate
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
|
9
|
+
# TODO might be a chance to use vagrant template system according to https://github.com/mitchellh/vagrant/issues/3231
|
10
|
+
def to_xml template_name = nil, data = binding
|
10
11
|
erb = template_name || self.class.to_s.split("::").last.downcase
|
11
12
|
path = File.join(File.dirname(__FILE__), "..", "templates",
|
12
13
|
"#{erb}.xml.erb")
|
13
14
|
template = File.read(path)
|
14
|
-
|
15
|
+
|
16
|
+
# TODO according to erubis documentation, we should rather use evaluate and forget about
|
17
|
+
# binding since the template may then change variables values
|
18
|
+
Erubis::Eruby.new(template, :trim => true).result(data)
|
15
19
|
end
|
16
20
|
|
17
21
|
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# Ripped from http://libvirt.org/html/libvirt-virterror.html#virErrorNumber.
|
2
|
+
module VagrantPlugins
|
3
|
+
module ProviderLibvirt
|
4
|
+
module Util
|
5
|
+
module ErrorCodes
|
6
|
+
VIR_ERR_OK = 0
|
7
|
+
VIR_ERR_INTERNAL_ERROR = 1 # internal error
|
8
|
+
VIR_ERR_NO_MEMORY = 2 # memory allocation failure
|
9
|
+
VIR_ERR_NO_SUPPORT = 3 # no support for this function
|
10
|
+
VIR_ERR_UNKNOWN_HOST = 4 # could not resolve hostname
|
11
|
+
VIR_ERR_NO_CONNECT = 5 # can't connect to hypervisor
|
12
|
+
VIR_ERR_INVALID_CONN = 6 # invalid connection object
|
13
|
+
VIR_ERR_INVALID_DOMAIN = 7 # invalid domain object
|
14
|
+
VIR_ERR_INVALID_ARG = 8 # invalid function argument
|
15
|
+
VIR_ERR_OPERATION_FAILED = 9 # a command to hypervisor failed
|
16
|
+
VIR_ERR_GET_FAILED = 10 # a HTTP GET command to failed
|
17
|
+
VIR_ERR_POST_FAILED = 11 # a HTTP POST command to failed
|
18
|
+
VIR_ERR_HTTP_ERROR = 12 # unexpected HTTP error code
|
19
|
+
VIR_ERR_SEXPR_SERIAL = 13 # failure to serialize an S-Expr
|
20
|
+
VIR_ERR_NO_XEN = 14 # could not open Xen hypervisor control
|
21
|
+
VIR_ERR_XEN_CALL = 15 # failure doing an hypervisor call
|
22
|
+
VIR_ERR_OS_TYPE = 16 # unknown OS type
|
23
|
+
VIR_ERR_NO_KERNEL = 17 # missing kernel information
|
24
|
+
VIR_ERR_NO_ROOT = 18 # missing root device information
|
25
|
+
VIR_ERR_NO_SOURCE = 19 # missing source device information
|
26
|
+
VIR_ERR_NO_TARGET = 20 # missing target device information
|
27
|
+
VIR_ERR_NO_NAME = 21 # missing domain name information
|
28
|
+
VIR_ERR_NO_OS = 22 # missing domain OS information
|
29
|
+
VIR_ERR_NO_DEVICE = 23 # missing domain devices information
|
30
|
+
VIR_ERR_NO_XENSTORE = 24 # could not open Xen Store control
|
31
|
+
VIR_ERR_DRIVER_FULL = 25 # too many drivers registered
|
32
|
+
VIR_ERR_CALL_FAILED = 26 # not supported by the drivers (DEPRECATED)
|
33
|
+
VIR_ERR_XML_ERROR = 27 # an XML description is not well formed or broken
|
34
|
+
VIR_ERR_DOM_EXIST = 28 # the domain already exist
|
35
|
+
VIR_ERR_OPERATION_DENIED = 29 # operation forbidden on read-only connections
|
36
|
+
VIR_ERR_OPEN_FAILED = 30 # failed to open a conf file
|
37
|
+
VIR_ERR_READ_FAILED = 31 # failed to read a conf file
|
38
|
+
VIR_ERR_PARSE_FAILED = 32 # failed to parse a conf file
|
39
|
+
VIR_ERR_CONF_SYNTAX = 33 # failed to parse the syntax of a conf file
|
40
|
+
VIR_ERR_WRITE_FAILED = 34 # failed to write a conf file
|
41
|
+
VIR_ERR_XML_DETAIL = 35 # detail of an XML error
|
42
|
+
VIR_ERR_INVALID_NETWORK = 36 # invalid network object
|
43
|
+
VIR_ERR_NETWORK_EXIST = 37 # the network already exist
|
44
|
+
VIR_ERR_SYSTEM_ERROR = 38 # general system call failure
|
45
|
+
VIR_ERR_RPC = 39 # some sort of RPC error
|
46
|
+
VIR_ERR_GNUTLS_ERROR = 40 # error from a GNUTLS call
|
47
|
+
VIR_WAR_NO_NETWORK = 41 # failed to start network
|
48
|
+
VIR_ERR_NO_DOMAIN = 42 # domain not found or unexpectedly disappeared
|
49
|
+
VIR_ERR_NO_NETWORK = 43 # network not found
|
50
|
+
VIR_ERR_INVALID_MAC = 44 # invalid MAC address
|
51
|
+
VIR_ERR_AUTH_FAILED = 45 # authentication failed
|
52
|
+
VIR_ERR_INVALID_STORAGE_POOL = 46 # invalid storage pool object
|
53
|
+
VIR_ERR_INVALID_STORAGE_VOL = 47 # invalid storage vol object
|
54
|
+
VIR_WAR_NO_STORAGE = 48 # failed to start storage
|
55
|
+
VIR_ERR_NO_STORAGE_POOL = 49 # storage pool not found
|
56
|
+
VIR_ERR_NO_STORAGE_VOL = 50 # storage volume not found
|
57
|
+
VIR_WAR_NO_NODE = 51 # failed to start node driver
|
58
|
+
VIR_ERR_INVALID_NODE_DEVICE = 52 # invalid node device object
|
59
|
+
VIR_ERR_NO_NODE_DEVICE = 53 # node device not found
|
60
|
+
VIR_ERR_NO_SECURITY_MODEL = 54 # security model not found
|
61
|
+
VIR_ERR_OPERATION_INVALID = 55 # operation is not applicable at this time
|
62
|
+
VIR_WAR_NO_INTERFACE = 56 # failed to start interface driver
|
63
|
+
VIR_ERR_NO_INTERFACE = 57 # interface driver not running
|
64
|
+
VIR_ERR_INVALID_INTERFACE = 58 # invalid interface object
|
65
|
+
VIR_ERR_MULTIPLE_INTERFACES = 59 # more than one matching interface found
|
66
|
+
VIR_WAR_NO_NWFILTER = 60 # failed to start nwfilter driver
|
67
|
+
VIR_ERR_INVALID_NWFILTER = 61 # invalid nwfilter object
|
68
|
+
VIR_ERR_NO_NWFILTER = 62 # nw filter pool not found
|
69
|
+
VIR_ERR_BUILD_FIREWALL = 63 # nw filter pool not found
|
70
|
+
VIR_WAR_NO_SECRET = 64 # failed to start secret storage
|
71
|
+
VIR_ERR_INVALID_SECRET = 65 # invalid secret
|
72
|
+
VIR_ERR_NO_SECRET = 66 # secret not found
|
73
|
+
VIR_ERR_CONFIG_UNSUPPORTED = 67 # unsupported configuration construct
|
74
|
+
VIR_ERR_OPERATION_TIMEOUT = 68 # timeout occurred during operation
|
75
|
+
VIR_ERR_MIGRATE_PERSIST_FAILED = 69 # a migration worked, but making the VM persist on the dest host failed
|
76
|
+
VIR_ERR_HOOK_SCRIPT_FAILED = 70 # a synchronous hook script failed
|
77
|
+
VIR_ERR_INVALID_DOMAIN_SNAPSHOT = 71 # invalid domain snapshot
|
78
|
+
VIR_ERR_NO_DOMAIN_SNAPSHOT = 72 # domain snapshot not found
|
79
|
+
VIR_ERR_INVALID_STREAM = 73 # stream pointer not valid
|
80
|
+
VIR_ERR_ARGUMENT_UNSUPPORTED = 74 # valid API use but unsupported by the given driver
|
81
|
+
VIR_ERR_STORAGE_PROBE_FAILED = 75 # storage pool probe failed
|
82
|
+
VIR_ERR_STORAGE_POOL_BUILT = 76 # storage pool already built
|
83
|
+
VIR_ERR_SNAPSHOT_REVERT_RISKY = 77 # force was not requested for a risky domain snapshot revert
|
84
|
+
VIR_ERR_OPERATION_ABORTED = 78 # operation on a domain was canceled/aborted by user
|
85
|
+
VIR_ERR_AUTH_CANCELLED = 79 # authentication cancelled
|
86
|
+
VIR_ERR_NO_DOMAIN_METADATA = 80 # The metadata is not present
|
87
|
+
VIR_ERR_MIGRATE_UNSAFE = 81 # Migration is not safe
|
88
|
+
VIR_ERR_OVERFLOW = 82 # integer overflow
|
89
|
+
VIR_ERR_BLOCK_COPY_ACTIVE = 83 # action prevented by block copy job
|
90
|
+
VIR_ERR_OPERATION_UNSUPPORTED = 84 # The requested operation is not supported
|
91
|
+
VIR_ERR_SSH = 85 # error in ssh transport driver
|
92
|
+
VIR_ERR_AGENT_UNRESPONSIVE = 86 # guest agent is unresponsive, not running or not usable
|
93
|
+
VIR_ERR_RESOURCE_BUSY = 87 # resource is already in use
|
94
|
+
VIR_ERR_ACCESS_DENIED = 88 # operation on the object/resource was denied
|
95
|
+
VIR_ERR_DBUS_SERVICE = 89 # error from a dbus service
|
96
|
+
VIR_ERR_STORAGE_VOL_EXIST = 90 # the storage vol already exists
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
data/locales/en.yml
CHANGED
@@ -99,6 +99,8 @@ en:
|
|
99
99
|
No domain found. %{error_message}
|
100
100
|
attach_device_error: |-
|
101
101
|
Error while attaching new device to domain. %{error_message}
|
102
|
+
detach_device_error: |-
|
103
|
+
Error while detaching device from domain. %{error_message}
|
102
104
|
no_ip_address_error: |-
|
103
105
|
No IP address found.
|
104
106
|
management_network_error: |-
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vagrant-libvirt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.16
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lukas Stanek
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2014-
|
13
|
+
date: 2014-05-11 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: fog
|
@@ -116,15 +116,16 @@ files:
|
|
116
116
|
- lib/vagrant-libvirt/action/share_folders.rb
|
117
117
|
- lib/vagrant-libvirt/action/start_domain.rb
|
118
118
|
- lib/vagrant-libvirt/action/suspend_domain.rb
|
119
|
-
- lib/vagrant-libvirt/action/sync_folders.rb
|
120
|
-
- lib/vagrant-libvirt/action/timed_provision.rb
|
121
119
|
- lib/vagrant-libvirt/action/wait_till_up.rb
|
120
|
+
- lib/vagrant-libvirt/cap/mount_p9.rb
|
121
|
+
- lib/vagrant-libvirt/cap/synced_folder.rb
|
122
122
|
- lib/vagrant-libvirt/config.rb
|
123
123
|
- lib/vagrant-libvirt/errors.rb
|
124
124
|
- lib/vagrant-libvirt/plugin.rb
|
125
125
|
- lib/vagrant-libvirt/provider.rb
|
126
126
|
- lib/vagrant-libvirt/templates/default_storage_pool.xml.erb
|
127
127
|
- lib/vagrant-libvirt/templates/domain.xml.erb
|
128
|
+
- lib/vagrant-libvirt/templates/filesystem.xml.erb
|
128
129
|
- lib/vagrant-libvirt/templates/interface.xml.erb
|
129
130
|
- lib/vagrant-libvirt/templates/private_network.xml.erb
|
130
131
|
- lib/vagrant-libvirt/templates/public_interface.xml.erb
|
@@ -132,6 +133,7 @@ files:
|
|
132
133
|
- lib/vagrant-libvirt/util.rb
|
133
134
|
- lib/vagrant-libvirt/util/collection.rb
|
134
135
|
- lib/vagrant-libvirt/util/erb_template.rb
|
136
|
+
- lib/vagrant-libvirt/util/error_codes.rb
|
135
137
|
- lib/vagrant-libvirt/util/network_util.rb
|
136
138
|
- lib/vagrant-libvirt/util/timer.rb
|
137
139
|
- lib/vagrant-libvirt/version.rb
|
@@ -158,7 +160,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
158
160
|
version: '0'
|
159
161
|
requirements: []
|
160
162
|
rubyforge_project:
|
161
|
-
rubygems_version: 2.
|
163
|
+
rubygems_version: 2.2.2
|
162
164
|
signing_key:
|
163
165
|
specification_version: 4
|
164
166
|
summary: Vagrant provider for libvirt.
|
@@ -1,66 +0,0 @@
|
|
1
|
-
require "log4r"
|
2
|
-
require "vagrant/util/subprocess"
|
3
|
-
|
4
|
-
module VagrantPlugins
|
5
|
-
module ProviderLibvirt
|
6
|
-
module Action
|
7
|
-
# This middleware uses `rsync` to sync the folders over to the
|
8
|
-
# libvirt domain.
|
9
|
-
class SyncFolders
|
10
|
-
def initialize(app, env)
|
11
|
-
@app = app
|
12
|
-
@logger = Log4r::Logger.new("vagrant_libvirt::action::sync_folders")
|
13
|
-
end
|
14
|
-
|
15
|
-
def call(env)
|
16
|
-
@app.call(env)
|
17
|
-
|
18
|
-
ssh_info = env[:machine].ssh_info
|
19
|
-
|
20
|
-
env[:machine].config.vm.synced_folders.each do |id, data|
|
21
|
-
next if data[:type] == :nfs
|
22
|
-
proxycommand = "-o ProxyCommand='#{ssh_info[:proxy_command]}'" if ssh_info[:proxy_command]
|
23
|
-
hostpath = File.expand_path(data[:hostpath], env[:root_path])
|
24
|
-
guestpath = data[:guestpath]
|
25
|
-
|
26
|
-
# Make sure there is a trailing slash on the host path to
|
27
|
-
# avoid creating an additional directory with rsync
|
28
|
-
hostpath = "#{hostpath}/" if hostpath !~ /\/$/
|
29
|
-
|
30
|
-
env[:ui].info(I18n.t('vagrant_libvirt.rsync_folder',
|
31
|
-
:hostpath => hostpath,
|
32
|
-
:guestpath => guestpath))
|
33
|
-
|
34
|
-
# Create the guest path
|
35
|
-
env[:machine].communicate.sudo("mkdir -p '#{guestpath}'")
|
36
|
-
env[:machine].communicate.sudo(
|
37
|
-
"chown #{ssh_info[:username]} '#{guestpath}'")
|
38
|
-
|
39
|
-
# Rsync over to the guest path using the SSH info
|
40
|
-
command = [
|
41
|
-
'rsync', '--del', '--verbose', '--archive', '-z',
|
42
|
-
'--exclude', '.vagrant/',
|
43
|
-
'-e', "ssh -p #{ssh_info[:port]} #{proxycommand} -o StrictHostKeyChecking=no #{ssh_key_options(ssh_info)}",
|
44
|
-
hostpath,
|
45
|
-
"#{ssh_info[:username]}@#{ssh_info[:host]}:#{guestpath}"]
|
46
|
-
|
47
|
-
r = Vagrant::Util::Subprocess.execute(*command)
|
48
|
-
if r.exit_code != 0
|
49
|
-
raise Errors::RsyncError,
|
50
|
-
:guestpath => guestpath,
|
51
|
-
:hostpath => hostpath,
|
52
|
-
:stderr => r.stderr
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
private
|
57
|
-
|
58
|
-
def ssh_key_options(ssh_info)
|
59
|
-
# Ensure that `private_key_path` is an Array (for Vagrant < 1.4)
|
60
|
-
Array(ssh_info[:private_key_path]).map { |path| "-i '#{path}' " }.join
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
@@ -1,21 +0,0 @@
|
|
1
|
-
require 'vagrant-libvirt/util/timer'
|
2
|
-
|
3
|
-
module VagrantPlugins
|
4
|
-
module ProviderLibvirt
|
5
|
-
module Action
|
6
|
-
# This is the same as the builtin provision except it times the
|
7
|
-
# provisioner runs.
|
8
|
-
class TimedProvision < Vagrant::Action::Builtin::Provision
|
9
|
-
def run_provisioner(env)
|
10
|
-
timer = Util::Timer.time do
|
11
|
-
super
|
12
|
-
end
|
13
|
-
|
14
|
-
env[:metrics] ||= {}
|
15
|
-
env[:metrics]['provisioner_times'] ||= []
|
16
|
-
env[:metrics]['provisioner_times'] << [env[:provisioner].class.to_s, timer]
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|