vagrant-xenserver 0.0.12 → 0.0.13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/vagrant-xenserver/action.rb +20 -0
- data/lib/vagrant-xenserver/action/clone_vm.rb +6 -3
- data/lib/vagrant-xenserver/action/connect_xs.rb +16 -11
- data/lib/vagrant-xenserver/action/create_template.rb +40 -39
- data/lib/vagrant-xenserver/action/download_xva.rb +55 -50
- data/lib/vagrant-xenserver/action/read_state.rb +1 -0
- data/lib/vagrant-xenserver/action/upload_xva.rb +56 -54
- data/lib/vagrant-xenserver/errors.rb +5 -1
- data/lib/vagrant-xenserver/plugin.rb +34 -1
- data/lib/vagrant-xenserver/version.rb +1 -1
- data/locales/en.yml +3 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 863a12a0d4f0def43d9e81dc02d35aa71d2c2992
|
4
|
+
data.tar.gz: 72bb9e377c24be9a249c3d23cbe827d9be1c47a4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 24a88789435fd29b0f6a9c43bc31275bb4a260a444ccc1c9fd4e6f54c8d4f60d7ef99864aab262feebd229ca77dbf1b631875354c34cd7977869b74ebfe8eaf1
|
7
|
+
data.tar.gz: aa8d34e7b64708274df83a175c396fc49f44ac2e3e57daabb59e5b839225284362454e62b96074577bc4c92fc48d0408a6f218bbcb6cbde85209a14bc681919c
|
@@ -6,6 +6,11 @@ module VagrantPlugins
|
|
6
6
|
module Action
|
7
7
|
include Vagrant::Action::Builtin
|
8
8
|
@logger = Log4r::Logger.new('vagrant::xenserver::action')
|
9
|
+
@xvalock = Mutex.new
|
10
|
+
|
11
|
+
def self.getlock
|
12
|
+
@xvalock
|
13
|
+
end
|
9
14
|
|
10
15
|
def self.action_boot
|
11
16
|
Vagrant::Action::Builder.new.tap do |b|
|
@@ -212,6 +217,21 @@ module VagrantPlugins
|
|
212
217
|
end
|
213
218
|
end
|
214
219
|
|
220
|
+
def self.action_reload
|
221
|
+
Vagrant::Action::Builder.new.tap do |b|
|
222
|
+
b.use Call, IsCreated do |env1, b2|
|
223
|
+
if !env1[:result]
|
224
|
+
b2.use MessageNotCreated
|
225
|
+
next
|
226
|
+
end
|
227
|
+
|
228
|
+
b2.use ConfigValidate
|
229
|
+
b2.use action_halt
|
230
|
+
b2.use action_boot
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
215
235
|
action_root = Pathname.new(File.expand_path('../action', __FILE__))
|
216
236
|
autoload :CreateVIFs, action_root.join("create_vifs")
|
217
237
|
autoload :ConnectXS, action_root.join("connect_xs")
|
@@ -21,9 +21,12 @@ module VagrantPlugins
|
|
21
21
|
else
|
22
22
|
vm_name = env[:machine].provider_config.name
|
23
23
|
end
|
24
|
-
|
25
|
-
vm =
|
26
|
-
|
24
|
+
|
25
|
+
vm = nil
|
26
|
+
Action.getlock.synchronize do
|
27
|
+
vm = env[:xc].VM.clone(template_ref, vm_name)
|
28
|
+
env[:xc].VM.provision(vm)
|
29
|
+
end
|
27
30
|
|
28
31
|
env[:machine].id = vm
|
29
32
|
|
@@ -12,22 +12,28 @@ module VagrantPlugins
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def call(env)
|
15
|
-
|
16
|
-
|
15
|
+
config = env[:machine].provider_config
|
16
|
+
|
17
|
+
# Only even try to connect if we've got a hostname
|
18
|
+
if (not env[:xc]) && (not config.xs_host.nil?)
|
17
19
|
uri = URI::Generic.new(config.xs_use_ssl ? 'https' : 'http',
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
nil,
|
21
|
+
config.xs_host,
|
22
|
+
config.xs_port,
|
23
|
+
nil,
|
24
|
+
"/",
|
25
|
+
nil,
|
26
|
+
nil, nil)
|
25
27
|
env[:xc] = XenApi::Client.new(uri.to_s, timeout = config.api_timeout)
|
26
28
|
|
27
29
|
@logger.info("Connecting to XenServer")
|
28
30
|
|
29
|
-
|
31
|
+
begin
|
32
|
+
result = env[:xc].login_with_password(config.xs_username, config.xs_password)
|
33
|
+
rescue XenApi::Errors::SessionAuthenticationFailed
|
30
34
|
raise Errors::LoginError
|
35
|
+
rescue
|
36
|
+
raise Errors::ConnectionError
|
31
37
|
end
|
32
38
|
|
33
39
|
@logger.info("Connected to XenServer")
|
@@ -39,4 +45,3 @@ module VagrantPlugins
|
|
39
45
|
end
|
40
46
|
end
|
41
47
|
end
|
42
|
-
|
@@ -24,58 +24,59 @@ module VagrantPlugins
|
|
24
24
|
# Let's create a VM and attach the uploaded VDI to it.
|
25
25
|
# First see if we've done that already:
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
vmr["other_config"]["
|
31
|
-
|
27
|
+
Action.getlock.synchronize do
|
28
|
+
templates = env[:xc].VM.get_all_records_where("field \"is_a_template\"=\"true\"")
|
29
|
+
template = templates.detect { |vm,vmr|
|
30
|
+
vmr["other_config"]["box_name"] == box_name &&
|
31
|
+
vmr["other_config"]["box_version"] == box_version
|
32
|
+
}
|
32
33
|
|
33
|
-
|
34
|
-
|
34
|
+
if template.nil?
|
35
|
+
vdi_ref = env[:box_vdi]
|
35
36
|
|
36
|
-
|
37
|
+
oim = env[:xc].VM.get_by_name_label("Other install media")[0]
|
37
38
|
|
38
|
-
|
39
|
+
template_name = "#{box_name}.#{box_version}"
|
39
40
|
|
40
|
-
|
41
|
+
template_ref = env[:xc].VM.clone(oim,template_name)
|
41
42
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
43
|
+
vbd_record = {
|
44
|
+
'VM' => template_ref,
|
45
|
+
'VDI' => env[:box_vdi],
|
46
|
+
'userdevice' => '0',
|
47
|
+
'bootable' => true,
|
48
|
+
'mode' => 'RW',
|
49
|
+
'type' => 'Disk',
|
50
|
+
'unpluggable' => false,
|
51
|
+
'empty' => false,
|
52
|
+
'other_config' => {},
|
53
|
+
'qos_algorithm_type' => '',
|
54
|
+
'qos_algorithm_params' => {}
|
55
|
+
}
|
55
56
|
|
56
|
-
|
57
|
+
vbd_res = env[:xc].VBD.create(vbd_record)
|
57
58
|
|
58
|
-
|
59
|
+
@logger.info("vbd_res=" + vbd_res.to_s)
|
59
60
|
|
60
|
-
|
61
|
-
|
61
|
+
env[:xc].VM.add_to_other_config(template_ref, "box_name", box_name)
|
62
|
+
env[:xc].VM.add_to_other_config(template_ref, "box_version", box_version)
|
62
63
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
64
|
+
if env[:machine].provider_config.pv
|
65
|
+
env[:xc].VM.set_HVM_boot_policy(template_ref,"")
|
66
|
+
env[:xc].VM.set_PV_bootloader(template_ref,"pygrub")
|
67
|
+
end
|
67
68
|
|
68
|
-
|
69
|
-
|
69
|
+
mem = ((env[:machine].provider_config.memory) * (1024*1024)).to_s
|
70
|
+
env[:xc].VM.set_memory_limits(template_ref,mem,mem,mem,mem)
|
70
71
|
|
71
|
-
|
72
|
+
env[:template] = template_ref
|
72
73
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
74
|
+
else
|
75
|
+
@logger.info("Found pre-existing template for this box")
|
76
|
+
(template_ref, template_rec) = template
|
77
|
+
env[:template] = template_ref
|
78
|
+
end
|
77
79
|
end
|
78
|
-
|
79
80
|
end
|
80
81
|
|
81
82
|
@app.call env
|
@@ -26,68 +26,73 @@ module VagrantPlugins
|
|
26
26
|
# Check whether we've already downloaded a VM from this URL
|
27
27
|
# When we do, we set an other_config key 'xva_url', so we
|
28
28
|
# can just scan through the VMs looking for it.
|
29
|
-
templates = env[:xc].VM.get_all_records_where("field \"is_a_template\"=\"true\"")
|
30
|
-
template = templates.detect { |vm,vmr|
|
31
|
-
vmr["other_config"]["box_name"] == box_name &&
|
32
|
-
vmr["other_config"]["box_version"] == box_version
|
33
|
-
}
|
34
|
-
|
35
|
-
@logger.info("template="+template.to_s)
|
36
|
-
|
37
|
-
if template.nil? && (not xva_url.nil?)
|
38
|
-
# No template, let's download it.
|
39
|
-
pool=env[:xc].pool.get_all
|
40
|
-
default_sr=env[:xc].pool.get_default_SR(pool[0])
|
41
|
-
|
42
|
-
env[:ui].output("Downloading XVA. This may take some time. Source URL: "+xva_url)
|
43
|
-
task = env[:xc].Async.VM.import(xva_url, default_sr, false, false)
|
44
|
-
|
45
|
-
begin
|
46
|
-
sleep(2.0)
|
47
|
-
task_status = env[:xc].task.get_status(task)
|
48
|
-
task_progress = env[:xc].task.get_progress(task) * 100.0
|
49
|
-
output = "Progress: #{task_progress.round(0)}%"
|
50
|
-
env[:ui].clear_line
|
51
|
-
env[:ui].detail(output, new_line: false)
|
52
|
-
end while task_status == "pending"
|
53
29
|
|
54
|
-
|
30
|
+
template = nil
|
55
31
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
32
|
+
Action.getlock.synchronize do
|
33
|
+
templates = env[:xc].VM.get_all_records_where("field \"is_a_template\"=\"true\"")
|
34
|
+
template = templates.detect { |vm,vmr|
|
35
|
+
vmr["other_config"]["box_name"] == box_name &&
|
36
|
+
vmr["other_config"]["box_version"] == box_version
|
37
|
+
}
|
38
|
+
|
39
|
+
@logger.info("template="+template.to_s)
|
61
40
|
|
62
|
-
|
41
|
+
if template.nil? && (not xva_url.nil?)
|
42
|
+
# No template, let's download it.
|
43
|
+
pool=env[:xc].pool.get_all
|
44
|
+
default_sr=env[:xc].pool.get_default_SR(pool[0])
|
63
45
|
|
64
|
-
|
46
|
+
env[:ui].output("Downloading XVA. This may take some time. Source URL: "+xva_url)
|
47
|
+
task = env[:xc].Async.VM.import(xva_url, default_sr, false, false)
|
65
48
|
|
66
|
-
|
67
|
-
|
49
|
+
begin
|
50
|
+
sleep(2.0)
|
51
|
+
task_status = env[:xc].task.get_status(task)
|
52
|
+
task_progress = env[:xc].task.get_progress(task) * 100.0
|
53
|
+
output = "Progress: #{task_progress.round(0)}%"
|
54
|
+
env[:ui].clear_line
|
55
|
+
env[:ui].detail(output, new_line: false)
|
56
|
+
end while task_status == "pending"
|
57
|
+
|
58
|
+
env[:ui].clear_line
|
59
|
+
|
60
|
+
if task_status != "success"
|
61
|
+
# Task failed - let's find out why:
|
62
|
+
error_list = env[:xc].task.get_error_info(task)
|
63
|
+
MyUtil::Exnhandler.handle("Async.VM.import", error_list)
|
64
|
+
end
|
68
65
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
66
|
+
task_result = env[:xc].task.get_result(task)
|
67
|
+
|
68
|
+
doc = REXML::Document.new(task_result)
|
69
|
+
|
70
|
+
@logger.debug("task_result=\"#{task_result}\"")
|
71
|
+
template_ref = doc.elements['value/array/data/value'].text
|
72
|
+
|
73
|
+
# Make sure it's really a template, and add the xva_url to other_config:
|
74
|
+
env[:xc].VM.set_is_a_template(template_ref,true)
|
75
|
+
env[:xc].VM.add_to_other_config(template_ref,"xva_url",xva_url)
|
76
|
+
env[:xc].VM.add_to_other_config(template_ref,"box_name",box_name)
|
77
|
+
env[:xc].VM.add_to_other_config(template_ref,"box_version",box_version)
|
74
78
|
|
75
79
|
# Hackity hack: HVM booting guests don't need to set the bootable flag
|
76
80
|
# on their VBDs, but PV do. Let's set bootable=true on VBD device=0
|
77
81
|
# just in case.
|
78
82
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
83
|
+
vbds = env[:xc].VM.get_VBDs(template_ref)
|
84
|
+
vbds.each { |vbd|
|
85
|
+
if env[:xc].VBD.get_userdevice(vbd) == "0"
|
86
|
+
env[:xc].VBD.set_bootable(vbd, true)
|
87
|
+
end
|
88
|
+
}
|
89
|
+
env[:template] = template_ref
|
90
|
+
else
|
91
|
+
(template_ref, template_rec) = template
|
92
|
+
env[:template] = template_ref
|
93
|
+
end
|
89
94
|
end
|
90
|
-
|
95
|
+
|
91
96
|
@app.call(env)
|
92
97
|
end
|
93
98
|
end
|
@@ -16,78 +16,80 @@ module VagrantPlugins
|
|
16
16
|
box_name = env[:machine].box.name.to_s
|
17
17
|
box_version = env[:machine].box.version.to_s
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
vmr["other_config"]["
|
23
|
-
|
19
|
+
Action.getlock.synchronize do
|
20
|
+
templates = env[:xc].VM.get_all_records_where("field \"is_a_template\"=\"true\"")
|
21
|
+
template = templates.detect { |vm,vmr|
|
22
|
+
vmr["other_config"]["box_name"] == box_name &&
|
23
|
+
vmr["other_config"]["box_version"] == box_version
|
24
|
+
}
|
24
25
|
|
25
|
-
|
26
|
+
box_xva_file = env[:machine].box.directory.join('box.xva').to_s
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
if File.exist?(box_xva_file) && template.nil?
|
29
|
+
#box_image_file = env[:machine].box.directory.join('export.xva').to_s
|
30
|
+
hostname = env[:machine].provider_config.xs_host
|
31
|
+
session = env[:session]
|
31
32
|
|
32
|
-
|
33
|
-
|
33
|
+
@logger.info("box name=" + env[:machine].box.name.to_s)
|
34
|
+
@logger.info("box version=" + env[:machine].box.version.to_s)
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
|
36
|
+
# Create a task to so we can get the result of the upload
|
37
|
+
task = env[:xc].task.create("vagrant-xva-upload",
|
38
|
+
"Task to track progress of the XVA upload from vagrant")
|
38
39
|
|
39
|
-
|
40
|
+
url = "https://#{hostname}/import?session_id=#{env[:xc].xenapi_session}&task_id=#{task}"
|
40
41
|
|
41
|
-
|
42
|
-
|
43
|
-
|
42
|
+
uploader_options = {}
|
43
|
+
uploader_options[:ui] = env[:ui]
|
44
|
+
uploader_options[:insecure] = true
|
44
45
|
|
45
|
-
|
46
|
+
uploader = MyUtil::Uploader.new(box_xva_file, url, uploader_options)
|
46
47
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
48
|
+
begin
|
49
|
+
uploader.upload!
|
50
|
+
rescue
|
51
|
+
env[:xc].task.cancel(task)
|
52
|
+
end
|
52
53
|
|
53
|
-
|
54
|
+
task_status = ""
|
54
55
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
56
|
+
begin
|
57
|
+
sleep(0.2)
|
58
|
+
task_status = env[:xc].task.get_status(task)
|
59
|
+
end while task_status == "pending"
|
59
60
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
61
|
+
if task_status != "success"
|
62
|
+
# Task failed - let's find out why:
|
63
|
+
error_list = env[:xc].task.get_error_info(task)
|
64
|
+
MyUtil::Exnhandler.handle("VM.import", error_list)
|
65
|
+
end
|
65
66
|
|
66
|
-
|
67
|
+
task_result = env[:xc].task.get_result(task)
|
67
68
|
|
68
|
-
|
69
|
+
doc = REXML::Document.new(task_result)
|
69
70
|
|
70
|
-
|
71
|
-
|
71
|
+
@logger.debug("task_result=\"#{task_result}\"")
|
72
|
+
template_ref = doc.elements['value/array/data/value'].text
|
72
73
|
|
73
|
-
|
74
|
+
@logger.info("template_ref=" + template_ref)
|
74
75
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
76
|
+
# Make sure it's really a template, and add the xva_url to other_config:
|
77
|
+
env[:xc].VM.set_is_a_template(template_ref,true)
|
78
|
+
env[:xc].VM.add_to_other_config(template_ref,"box_name",box_name)
|
79
|
+
env[:xc].VM.add_to_other_config(template_ref,"box_version",box_version)
|
79
80
|
|
80
|
-
|
81
|
-
|
82
|
-
|
81
|
+
# Hackity hack: HVM booting guests don't need to set the bootable flag
|
82
|
+
# on their VBDs, but PV do. Let's set bootable=true on VBD device=0
|
83
|
+
# just in case.
|
83
84
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
85
|
+
vbds = env[:xc].VM.get_VBDs(template_ref)
|
86
|
+
vbds.each { |vbd|
|
87
|
+
if env[:xc].VBD.get_userdevice(vbd) == "0"
|
88
|
+
env[:xc].VBD.set_bootable(vbd, true)
|
89
|
+
end
|
90
|
+
}
|
91
|
+
env[:template] = template_ref
|
92
|
+
end
|
91
93
|
end
|
92
94
|
|
93
95
|
@app.call(env)
|
@@ -20,16 +20,49 @@ module VagrantPlugins
|
|
20
20
|
end
|
21
21
|
|
22
22
|
provider('xenserver', parallel: true) do
|
23
|
+
# Setup logging and i18n
|
24
|
+
setup_logging
|
23
25
|
setup_i18n
|
24
26
|
|
25
|
-
|
27
|
+
# Return the provider
|
28
|
+
require_relative "provider"
|
26
29
|
Provider
|
27
30
|
end
|
28
31
|
|
32
|
+
# This initializes the internationalization strings.
|
29
33
|
def self.setup_i18n
|
30
34
|
I18n.load_path << File.expand_path('locales/en.yml',
|
31
35
|
XenServer.source_root)
|
32
36
|
I18n.reload!
|
37
|
+
end
|
38
|
+
|
39
|
+
# This sets up our log level to be whatever VAGRANT_LOG is.
|
40
|
+
def self.setup_logging
|
41
|
+
require "log4r"
|
42
|
+
|
43
|
+
level = nil
|
44
|
+
begin
|
45
|
+
level = Log4r.const_get(ENV["VAGRANT_LOG"].upcase)
|
46
|
+
rescue NameError
|
47
|
+
# This means that the logging constant wasn't found,
|
48
|
+
# which is fine. We just keep `level` as `nil`. But
|
49
|
+
# we tell the user.
|
50
|
+
level = nil
|
51
|
+
end
|
52
|
+
|
53
|
+
# Some constants, such as "true" resolve to booleans, so the
|
54
|
+
# above error checking doesn't catch it. This will check to make
|
55
|
+
# sure that the log level is an integer, as Log4r requires.
|
56
|
+
level = nil if !level.is_a?(Integer)
|
57
|
+
|
58
|
+
# Set the logging level on all "vagrant" namespaced
|
59
|
+
# logs as long as we have a valid level.
|
60
|
+
if level
|
61
|
+
logger = Log4r::Logger.new("vagrant_xenserver")
|
62
|
+
logger.outputters = Log4r::Outputter.stderr
|
63
|
+
logger.level = level
|
64
|
+
logger = nil
|
65
|
+
end
|
33
66
|
end
|
34
67
|
end
|
35
68
|
end
|
data/locales/en.yml
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vagrant-xenserver
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jon Ludlam
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-06-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -134,7 +134,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
134
134
|
version: '0'
|
135
135
|
requirements: []
|
136
136
|
rubyforge_project:
|
137
|
-
rubygems_version: 2.5.
|
137
|
+
rubygems_version: 2.5.2
|
138
138
|
signing_key:
|
139
139
|
specification_version: 4
|
140
140
|
summary: Enables Vagrant to manage XenServers.
|