vagrant-libvirt 0.0.41 → 0.0.42
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/.coveralls.yml +1 -0
- data/.github/issue_template.md +37 -0
- data/.gitignore +21 -0
- data/.travis.yml +24 -0
- data/Gemfile +26 -0
- data/LICENSE +22 -0
- data/README.md +1380 -0
- data/Rakefile +8 -0
- data/example_box/README.md +29 -0
- data/example_box/Vagrantfile +60 -0
- data/example_box/metadata.json +5 -0
- data/lib/vagrant-libvirt.rb +29 -0
- data/lib/vagrant-libvirt/action.rb +370 -0
- data/lib/vagrant-libvirt/action/create_domain.rb +322 -0
- data/lib/vagrant-libvirt/action/create_domain_volume.rb +87 -0
- data/lib/vagrant-libvirt/action/create_network_interfaces.rb +302 -0
- data/lib/vagrant-libvirt/action/create_networks.rb +361 -0
- data/lib/vagrant-libvirt/action/destroy_domain.rb +83 -0
- data/lib/vagrant-libvirt/action/destroy_networks.rb +95 -0
- data/lib/vagrant-libvirt/action/forward_ports.rb +227 -0
- data/lib/vagrant-libvirt/action/halt_domain.rb +41 -0
- data/lib/vagrant-libvirt/action/handle_box_image.rb +156 -0
- data/lib/vagrant-libvirt/action/handle_storage_pool.rb +57 -0
- data/lib/vagrant-libvirt/action/is_created.rb +18 -0
- data/lib/vagrant-libvirt/action/is_running.rb +21 -0
- data/lib/vagrant-libvirt/action/is_suspended.rb +42 -0
- data/lib/vagrant-libvirt/action/message_already_created.rb +16 -0
- data/lib/vagrant-libvirt/action/message_not_created.rb +16 -0
- data/lib/vagrant-libvirt/action/message_not_running.rb +16 -0
- data/lib/vagrant-libvirt/action/message_not_suspended.rb +16 -0
- data/lib/vagrant-libvirt/action/message_will_not_destroy.rb +17 -0
- data/lib/vagrant-libvirt/action/package_domain.rb +105 -0
- data/lib/vagrant-libvirt/action/prepare_nfs_settings.rb +94 -0
- data/lib/vagrant-libvirt/action/prepare_nfs_valid_ids.rb +17 -0
- data/lib/vagrant-libvirt/action/prune_nfs_exports.rb +27 -0
- data/lib/vagrant-libvirt/action/read_mac_addresses.rb +40 -0
- data/lib/vagrant-libvirt/action/remove_libvirt_image.rb +20 -0
- data/lib/vagrant-libvirt/action/remove_stale_volume.rb +50 -0
- data/lib/vagrant-libvirt/action/resume_domain.rb +34 -0
- data/lib/vagrant-libvirt/action/set_boot_order.rb +109 -0
- data/lib/vagrant-libvirt/action/set_name_of_domain.rb +64 -0
- data/lib/vagrant-libvirt/action/share_folders.rb +71 -0
- data/lib/vagrant-libvirt/action/start_domain.rb +307 -0
- data/lib/vagrant-libvirt/action/suspend_domain.rb +40 -0
- data/lib/vagrant-libvirt/action/wait_till_up.rb +109 -0
- data/lib/vagrant-libvirt/cap/mount_p9.rb +42 -0
- data/lib/vagrant-libvirt/cap/nic_mac_addresses.rb +17 -0
- data/lib/vagrant-libvirt/cap/synced_folder.rb +113 -0
- data/lib/vagrant-libvirt/config.rb +746 -0
- data/lib/vagrant-libvirt/driver.rb +118 -0
- data/lib/vagrant-libvirt/errors.rb +153 -0
- data/lib/vagrant-libvirt/plugin.rb +92 -0
- data/lib/vagrant-libvirt/provider.rb +130 -0
- data/lib/vagrant-libvirt/templates/default_storage_pool.xml.erb +13 -0
- data/lib/vagrant-libvirt/templates/domain.xml.erb +244 -0
- data/lib/vagrant-libvirt/templates/private_network.xml.erb +42 -0
- data/lib/vagrant-libvirt/templates/public_interface.xml.erb +26 -0
- data/lib/vagrant-libvirt/util.rb +11 -0
- data/lib/vagrant-libvirt/util/collection.rb +19 -0
- data/lib/vagrant-libvirt/util/erb_template.rb +22 -0
- data/lib/vagrant-libvirt/util/error_codes.rb +100 -0
- data/lib/vagrant-libvirt/util/network_util.rb +151 -0
- data/lib/vagrant-libvirt/util/timer.rb +17 -0
- data/lib/vagrant-libvirt/version.rb +5 -0
- data/locales/en.yml +162 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/support/environment_helper.rb +46 -0
- data/spec/support/libvirt_context.rb +30 -0
- data/spec/support/sharedcontext.rb +34 -0
- data/spec/unit/action/destroy_domain_spec.rb +97 -0
- data/spec/unit/action/set_name_of_domain_spec.rb +21 -0
- data/spec/unit/action/wait_till_up_spec.rb +127 -0
- data/spec/unit/config_spec.rb +113 -0
- data/spec/unit/templates/domain_all_settings.xml +137 -0
- data/spec/unit/templates/domain_defaults.xml +46 -0
- data/spec/unit/templates/domain_spec.rb +84 -0
- data/tools/create_box.sh +130 -0
- data/tools/prepare_redhat_for_box.sh +119 -0
- data/vagrant-libvirt.gemspec +54 -0
- metadata +93 -3
@@ -0,0 +1,227 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module ProviderLibvirt
|
3
|
+
module Action
|
4
|
+
# Adds support for vagrant's `forward_ports` configuration directive.
|
5
|
+
class ForwardPorts
|
6
|
+
@@lock = Mutex.new
|
7
|
+
|
8
|
+
def initialize(app, _env)
|
9
|
+
@app = app
|
10
|
+
@logger = Log4r::Logger.new('vagrant_libvirt::action::forward_ports')
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(env)
|
14
|
+
@env = env
|
15
|
+
|
16
|
+
# Get the ports we're forwarding
|
17
|
+
env[:forwarded_ports] = compile_forwarded_ports(env[:machine].config)
|
18
|
+
|
19
|
+
# Warn if we're port forwarding to any privileged ports
|
20
|
+
env[:forwarded_ports].each do |fp|
|
21
|
+
next unless fp[:host] <= 1024
|
22
|
+
env[:ui].warn I18n.t(
|
23
|
+
'vagrant.actions.vm.forward_ports.privileged_ports'
|
24
|
+
)
|
25
|
+
break
|
26
|
+
end
|
27
|
+
|
28
|
+
# Continue, we need the VM to be booted in order to grab its IP
|
29
|
+
@app.call env
|
30
|
+
|
31
|
+
if @env[:forwarded_ports].any?
|
32
|
+
env[:ui].info I18n.t('vagrant.actions.vm.forward_ports.forwarding')
|
33
|
+
forward_ports
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def forward_ports
|
38
|
+
@env[:forwarded_ports].each do |fp|
|
39
|
+
message_attributes = {
|
40
|
+
adapter: fp[:adapter] || 'eth0',
|
41
|
+
guest_port: fp[:guest],
|
42
|
+
host_port: fp[:host]
|
43
|
+
}
|
44
|
+
|
45
|
+
@env[:ui].info(I18n.t(
|
46
|
+
'vagrant.actions.vm.forward_ports.forwarding_entry',
|
47
|
+
message_attributes
|
48
|
+
))
|
49
|
+
|
50
|
+
if fp[:protocol] == 'udp'
|
51
|
+
env[:ui].warn I18n.t('vagrant_libvirt.warnings.forwarding_udp')
|
52
|
+
next
|
53
|
+
end
|
54
|
+
|
55
|
+
ssh_pid = redirect_port(
|
56
|
+
@env[:machine],
|
57
|
+
fp[:host_ip] || 'localhost',
|
58
|
+
fp[:host],
|
59
|
+
fp[:guest_ip] || @env[:machine].provider.ssh_info[:host],
|
60
|
+
fp[:guest],
|
61
|
+
fp[:gateway_ports] || false
|
62
|
+
)
|
63
|
+
store_ssh_pid(fp[:host], ssh_pid)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def compile_forwarded_ports(config)
|
70
|
+
mappings = {}
|
71
|
+
|
72
|
+
config.vm.networks.each do |type, options|
|
73
|
+
next if options[:disabled]
|
74
|
+
|
75
|
+
next unless type == :forwarded_port && options[:id] != 'ssh'
|
76
|
+
if options.fetch(:host_ip, '').to_s.strip.empty?
|
77
|
+
options.delete(:host_ip)
|
78
|
+
end
|
79
|
+
mappings[options[:host]] = options
|
80
|
+
end
|
81
|
+
|
82
|
+
mappings.values
|
83
|
+
end
|
84
|
+
|
85
|
+
def redirect_port(machine, host_ip, host_port, guest_ip, guest_port,
|
86
|
+
gateway_ports)
|
87
|
+
ssh_info = machine.ssh_info
|
88
|
+
params = %W(
|
89
|
+
-L
|
90
|
+
#{host_ip}:#{host_port}:#{guest_ip}:#{guest_port}
|
91
|
+
-N
|
92
|
+
#{ssh_info[:host]}
|
93
|
+
).join(' ')
|
94
|
+
params += ' -g' if gateway_ports
|
95
|
+
|
96
|
+
options = (%W(
|
97
|
+
User=#{ssh_info[:username]}
|
98
|
+
Port=#{ssh_info[:port]}
|
99
|
+
UserKnownHostsFile=/dev/null
|
100
|
+
StrictHostKeyChecking=no
|
101
|
+
PasswordAuthentication=no
|
102
|
+
ForwardX11=#{ssh_info[:forward_x11] ? 'yes' : 'no'}
|
103
|
+
IdentitiesOnly=#{ssh_info[:keys_only] ? 'yes' : 'no'}
|
104
|
+
) + ssh_info[:private_key_path].map do |pk|
|
105
|
+
"IdentityFile='\"#{pk}\"'"
|
106
|
+
end).map { |s| s.prepend('-o ') }.join(' ')
|
107
|
+
|
108
|
+
options += " -o ProxyCommand=\"#{ssh_info[:proxy_command]}\"" if machine.provider_config.connect_via_ssh
|
109
|
+
|
110
|
+
# TODO: instead of this, try and lock and get the stdin from spawn...
|
111
|
+
ssh_cmd = 'exec '
|
112
|
+
if host_port <= 1024
|
113
|
+
@@lock.synchronize do
|
114
|
+
# TODO: add i18n
|
115
|
+
@env[:ui].info 'Requesting sudo for host port(s) <= 1024'
|
116
|
+
r = system('sudo -v')
|
117
|
+
if r
|
118
|
+
ssh_cmd << 'sudo ' # add sudo prefix
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
ssh_cmd << "ssh #{options} #{params}"
|
124
|
+
|
125
|
+
@logger.debug "Forwarding port with `#{ssh_cmd}`"
|
126
|
+
log_file = ssh_forward_log_file(host_ip, host_port,
|
127
|
+
guest_ip, guest_port)
|
128
|
+
@logger.info "Logging to #{log_file}"
|
129
|
+
spawn(ssh_cmd, [:out, :err] => [log_file, 'w'])
|
130
|
+
end
|
131
|
+
|
132
|
+
def ssh_forward_log_file(host_ip, host_port, guest_ip, guest_port)
|
133
|
+
log_dir = @env[:machine].data_dir.join('logs')
|
134
|
+
log_dir.mkdir unless log_dir.directory?
|
135
|
+
File.join(
|
136
|
+
log_dir,
|
137
|
+
'ssh-forwarding-%s_%s-%s_%s.log' %
|
138
|
+
[host_ip, host_port, guest_ip, guest_port]
|
139
|
+
)
|
140
|
+
end
|
141
|
+
|
142
|
+
def store_ssh_pid(host_port, ssh_pid)
|
143
|
+
data_dir = @env[:machine].data_dir.join('pids')
|
144
|
+
data_dir.mkdir unless data_dir.directory?
|
145
|
+
|
146
|
+
data_dir.join("ssh_#{host_port}.pid").open('w') do |pid_file|
|
147
|
+
pid_file.write(ssh_pid)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
module VagrantPlugins
|
156
|
+
module ProviderLibvirt
|
157
|
+
module Action
|
158
|
+
# Cleans up ssh-forwarded ports on VM halt/destroy.
|
159
|
+
class ClearForwardedPorts
|
160
|
+
@@lock = Mutex.new
|
161
|
+
|
162
|
+
def initialize(app, _env)
|
163
|
+
@app = app
|
164
|
+
@logger = Log4r::Logger.new(
|
165
|
+
'vagrant_libvirt::action::clear_forward_ports'
|
166
|
+
)
|
167
|
+
end
|
168
|
+
|
169
|
+
def call(env)
|
170
|
+
@env = env
|
171
|
+
|
172
|
+
if ssh_pids.any?
|
173
|
+
env[:ui].info I18n.t(
|
174
|
+
'vagrant.actions.vm.clear_forward_ports.deleting'
|
175
|
+
)
|
176
|
+
ssh_pids.each do |tag|
|
177
|
+
next unless ssh_pid?(tag[:pid])
|
178
|
+
@logger.debug "Killing pid #{tag[:pid]}"
|
179
|
+
kill_cmd = ''
|
180
|
+
|
181
|
+
if tag[:port] <= 1024
|
182
|
+
kill_cmd << 'sudo ' # add sudo prefix
|
183
|
+
end
|
184
|
+
|
185
|
+
kill_cmd << "kill #{tag[:pid]}"
|
186
|
+
@@lock.synchronize do
|
187
|
+
system(kill_cmd)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
@logger.info 'Removing ssh pid files'
|
192
|
+
remove_ssh_pids
|
193
|
+
else
|
194
|
+
@logger.info 'No ssh pids found'
|
195
|
+
end
|
196
|
+
|
197
|
+
@app.call env
|
198
|
+
end
|
199
|
+
|
200
|
+
protected
|
201
|
+
|
202
|
+
def ssh_pids
|
203
|
+
glob = @env[:machine].data_dir.join('pids').to_s + '/ssh_*.pid'
|
204
|
+
@ssh_pids = Dir[glob].map do |file|
|
205
|
+
{
|
206
|
+
pid: File.read(file).strip.chomp,
|
207
|
+
port: File.basename(file)['ssh_'.length..-1 * ('.pid'.length + 1)].to_i
|
208
|
+
}
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
def ssh_pid?(pid)
|
213
|
+
@logger.debug 'Checking if #{pid} is an ssh process '\
|
214
|
+
'with `ps -o cmd= #{pid}`'
|
215
|
+
`ps -o cmd= #{pid}`.strip.chomp =~ /ssh/
|
216
|
+
end
|
217
|
+
|
218
|
+
def remove_ssh_pids
|
219
|
+
glob = @env[:machine].data_dir.join('pids').to_s + '/ssh_*.pid'
|
220
|
+
Dir[glob].each do |file|
|
221
|
+
File.delete file
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'log4r'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module ProviderLibvirt
|
5
|
+
module Action
|
6
|
+
# Halt the domain.
|
7
|
+
class HaltDomain
|
8
|
+
def initialize(app, _env)
|
9
|
+
@logger = Log4r::Logger.new('vagrant_libvirt::action::halt_domain')
|
10
|
+
@app = app
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(env)
|
14
|
+
env[:ui].info(I18n.t('vagrant_libvirt.halt_domain'))
|
15
|
+
|
16
|
+
domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s)
|
17
|
+
raise Errors::NoDomainError if domain.nil?
|
18
|
+
|
19
|
+
begin
|
20
|
+
env[:machine].guest.capability(:halt)
|
21
|
+
rescue
|
22
|
+
@logger.info('Trying libvirt graceful shutdown.')
|
23
|
+
domain.shutdown
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
begin
|
28
|
+
domain.wait_for(30) do
|
29
|
+
!ready?
|
30
|
+
end
|
31
|
+
rescue Fog::Errors::TimeoutError
|
32
|
+
@logger.info('VM is still running. Calling force poweroff.')
|
33
|
+
domain.poweroff
|
34
|
+
end
|
35
|
+
|
36
|
+
@app.call(env)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
require 'log4r'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module ProviderLibvirt
|
5
|
+
module Action
|
6
|
+
class HandleBoxImage
|
7
|
+
@@lock = Mutex.new
|
8
|
+
|
9
|
+
def initialize(app, _env)
|
10
|
+
@logger = Log4r::Logger.new('vagrant_libvirt::action::handle_box_image')
|
11
|
+
@app = app
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
# Verify box metadata for mandatory values.
|
16
|
+
#
|
17
|
+
# Virtual size has to be set for allocating space in storage pool.
|
18
|
+
box_virtual_size = env[:machine].box.metadata['virtual_size']
|
19
|
+
raise Errors::NoBoxVirtualSizeSet if box_virtual_size.nil?
|
20
|
+
|
21
|
+
# Support qcow2 format only for now, but other formats with backing
|
22
|
+
# store capability should be usable.
|
23
|
+
box_format = env[:machine].box.metadata['format']
|
24
|
+
if box_format.nil?
|
25
|
+
raise Errors::NoBoxFormatSet
|
26
|
+
elsif box_format != 'qcow2'
|
27
|
+
raise Errors::WrongBoxFormatSet
|
28
|
+
end
|
29
|
+
|
30
|
+
# Get config options
|
31
|
+
config = env[:machine].provider_config
|
32
|
+
box_image_file = env[:machine].box.directory.join('box.img').to_s
|
33
|
+
env[:box_volume_name] = env[:machine].box.name.to_s.dup.gsub('/', '-VAGRANTSLASH-')
|
34
|
+
env[:box_volume_name] << "_vagrant_box_image_#{begin
|
35
|
+
env[:machine].box.version.to_s
|
36
|
+
rescue
|
37
|
+
''
|
38
|
+
end}.img"
|
39
|
+
|
40
|
+
# Override box_virtual_size
|
41
|
+
if config.machine_virtual_size
|
42
|
+
if config.machine_virtual_size < box_virtual_size
|
43
|
+
# Warn that a virtual size less than the box metadata size
|
44
|
+
# is not supported and will be ignored
|
45
|
+
env[:ui].warn I18n.t(
|
46
|
+
'vagrant_libvirt.warnings.ignoring_virtual_size_too_small',
|
47
|
+
requested: config.machine_virtual_size, minimum: box_virtual_size
|
48
|
+
)
|
49
|
+
else
|
50
|
+
env[:ui].info I18n.t('vagrant_libvirt.manual_resize_required')
|
51
|
+
box_virtual_size = config.machine_virtual_size
|
52
|
+
end
|
53
|
+
end
|
54
|
+
# save for use by later actions
|
55
|
+
env[:box_virtual_size] = box_virtual_size
|
56
|
+
|
57
|
+
# while inside the synchronize block take care not to call the next
|
58
|
+
# action in the chain, as must exit this block first to prevent
|
59
|
+
# locking all subsequent actions as well.
|
60
|
+
@@lock.synchronize do
|
61
|
+
# Don't continue if image already exists in storage pool.
|
62
|
+
break if ProviderLibvirt::Util::Collection.find_matching(
|
63
|
+
env[:machine].provider.driver.connection.volumes.all, env[:box_volume_name]
|
64
|
+
)
|
65
|
+
|
66
|
+
# Box is not available as a storage pool volume. Create and upload
|
67
|
+
# it as a copy of local box image.
|
68
|
+
env[:ui].info(I18n.t('vagrant_libvirt.uploading_volume'))
|
69
|
+
|
70
|
+
# Create new volume in storage pool
|
71
|
+
unless File.exist?(box_image_file)
|
72
|
+
raise Vagrant::Errors::BoxNotFound, name: env[:machine].box.name
|
73
|
+
end
|
74
|
+
box_image_size = File.size(box_image_file) # B
|
75
|
+
message = "Creating volume #{env[:box_volume_name]}"
|
76
|
+
message << " in storage pool #{config.storage_pool_name}."
|
77
|
+
@logger.info(message)
|
78
|
+
begin
|
79
|
+
fog_volume = env[:machine].provider.driver.connection.volumes.create(
|
80
|
+
name: env[:box_volume_name],
|
81
|
+
allocation: "#{box_image_size / 1024 / 1024}M",
|
82
|
+
capacity: "#{box_virtual_size}G",
|
83
|
+
format_type: box_format,
|
84
|
+
pool_name: config.storage_pool_name
|
85
|
+
)
|
86
|
+
rescue Fog::Errors::Error => e
|
87
|
+
raise Errors::FogCreateVolumeError,
|
88
|
+
error_message: e.message
|
89
|
+
end
|
90
|
+
|
91
|
+
# Upload box image to storage pool
|
92
|
+
ret = upload_image(box_image_file, config.storage_pool_name,
|
93
|
+
env[:box_volume_name], env) do |progress|
|
94
|
+
env[:ui].clear_line
|
95
|
+
env[:ui].report_progress(progress, box_image_size, false)
|
96
|
+
end
|
97
|
+
|
98
|
+
# Clear the line one last time since the progress meter doesn't
|
99
|
+
# disappear immediately.
|
100
|
+
env[:ui].clear_line
|
101
|
+
|
102
|
+
# If upload failed or was interrupted, remove created volume from
|
103
|
+
# storage pool.
|
104
|
+
if env[:interrupted] || !ret
|
105
|
+
begin
|
106
|
+
fog_volume.destroy
|
107
|
+
rescue
|
108
|
+
nil
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
@app.call(env)
|
114
|
+
end
|
115
|
+
|
116
|
+
protected
|
117
|
+
|
118
|
+
# Fog libvirt currently doesn't support uploading images to storage
|
119
|
+
# pool volumes. Use ruby-libvirt client instead.
|
120
|
+
def upload_image(image_file, pool_name, volume_name, env)
|
121
|
+
image_size = File.size(image_file) # B
|
122
|
+
|
123
|
+
begin
|
124
|
+
pool = env[:machine].provider.driver.connection.client.lookup_storage_pool_by_name(
|
125
|
+
pool_name
|
126
|
+
)
|
127
|
+
volume = pool.lookup_volume_by_name(volume_name)
|
128
|
+
stream = env[:machine].provider.driver.connection.client.stream
|
129
|
+
volume.upload(stream, offset = 0, length = image_size)
|
130
|
+
|
131
|
+
# Exception ProviderLibvirt::RetrieveError can be raised if buffer is
|
132
|
+
# longer than length accepted by API send function.
|
133
|
+
#
|
134
|
+
# TODO: How to find out if buffer is too large and what is the
|
135
|
+
# length that send function will accept?
|
136
|
+
|
137
|
+
buf_size = 1024 * 250 # 250K
|
138
|
+
progress = 0
|
139
|
+
open(image_file, 'rb') do |io|
|
140
|
+
while (buff = io.read(buf_size))
|
141
|
+
sent = stream.send buff
|
142
|
+
progress += sent
|
143
|
+
yield progress
|
144
|
+
end
|
145
|
+
end
|
146
|
+
rescue => e
|
147
|
+
raise Errors::ImageUploadError,
|
148
|
+
error_message: e.message
|
149
|
+
end
|
150
|
+
|
151
|
+
progress == image_size
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'log4r'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module ProviderLibvirt
|
5
|
+
module Action
|
6
|
+
class HandleStoragePool
|
7
|
+
include VagrantPlugins::ProviderLibvirt::Util::ErbTemplate
|
8
|
+
|
9
|
+
@@lock = Mutex.new
|
10
|
+
|
11
|
+
def initialize(app, _env)
|
12
|
+
@logger = Log4r::Logger.new('vagrant_libvirt::action::handle_storage_pool')
|
13
|
+
@app = app
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(env)
|
17
|
+
# Get config options.
|
18
|
+
config = env[:machine].provider_config
|
19
|
+
|
20
|
+
# while inside the synchronize block take care not to call the next
|
21
|
+
# action in the chain, as must exit this block first to prevent
|
22
|
+
# locking all subsequent actions as well.
|
23
|
+
@@lock.synchronize do
|
24
|
+
# Check for storage pool, where box image should be created
|
25
|
+
break if ProviderLibvirt::Util::Collection.find_matching(
|
26
|
+
env[:machine].provider.driver.connection.pools.all, config.storage_pool_name
|
27
|
+
)
|
28
|
+
|
29
|
+
@logger.info("No storage pool '#{config.storage_pool_name}' is available.")
|
30
|
+
|
31
|
+
# If user specified other pool than default, don't create default
|
32
|
+
# storage pool, just write error message.
|
33
|
+
raise Errors::NoStoragePool if config.storage_pool_name != 'default'
|
34
|
+
|
35
|
+
@logger.info("Creating storage pool 'default'")
|
36
|
+
|
37
|
+
# Fog libvirt currently doesn't support creating pools. Use
|
38
|
+
# ruby-libvirt client directly.
|
39
|
+
begin
|
40
|
+
libvirt_pool = env[:machine].provider.driver.connection.client.define_storage_pool_xml(
|
41
|
+
to_xml('default_storage_pool')
|
42
|
+
)
|
43
|
+
libvirt_pool.build
|
44
|
+
libvirt_pool.create
|
45
|
+
rescue => e
|
46
|
+
raise Errors::CreatingStoragePoolError,
|
47
|
+
error_message: e.message
|
48
|
+
end
|
49
|
+
raise Errors::NoStoragePool unless libvirt_pool
|
50
|
+
end
|
51
|
+
|
52
|
+
@app.call(env)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|