vagrant-proxmox 0.0.9 → 0.0.10
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/lib/sanity_checks.rb +1 -1
- data/lib/vagrant-proxmox/action.rb +38 -4
- data/lib/vagrant-proxmox/action/adjust_forwarded_port_params.rb +42 -0
- data/lib/vagrant-proxmox/action/clone_vm.rb +55 -0
- data/lib/vagrant-proxmox/action/config_clone.rb +98 -0
- data/lib/vagrant-proxmox/action/create_vm.rb +15 -0
- data/lib/vagrant-proxmox/action/proxmox_action.rb +21 -1
- data/lib/vagrant-proxmox/action/read_ssh_info.rb +2 -0
- data/lib/vagrant-proxmox/config.rb +28 -4
- data/lib/vagrant-proxmox/errors.rb +12 -0
- data/lib/vagrant-proxmox/proxmox/connection.rb +47 -1
- data/lib/vagrant-proxmox/version.rb +1 -1
- data/spec/provider_spec.rb +17 -14
- metadata +39 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 839f7c29c05343449fbed0cdc2979032c626b320
|
4
|
+
data.tar.gz: c6054dbe620fc0899fb5397e4c41fecfacdce356
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aa1d00cbc158511c2a1e7c1aa8ce0dc432a161eae627ac4e0cf624c0214a2974f00bc4f756f9cde48b5405794cbbf5d73cc2778b41fc6ee04c047ac02851270d
|
7
|
+
data.tar.gz: b731ec46291d842e627c3c606af0f143705945d759b0aca7851255c56cb09f848f04a96691cc31ea15f65748231a51f172af16eccb47984390d4ff2c604947b9
|
data/lib/sanity_checks.rb
CHANGED
@@ -7,7 +7,7 @@ end
|
|
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
9
|
if Vagrant::VERSION < '1.4.0'
|
10
|
-
fail 'The Vagrant Proxmox plugin is only compatible with Vagrant 1.
|
10
|
+
fail 'The Vagrant Proxmox plugin is only compatible with Vagrant 1.4+'
|
11
11
|
end
|
12
12
|
|
13
13
|
if RUBY_VERSION.to_i < 2
|
@@ -46,8 +46,8 @@ module VagrantPlugins
|
|
46
46
|
b2.use MessageUploadServerError
|
47
47
|
end
|
48
48
|
end
|
49
|
-
elsif env1[:machine].provider_config.vm_type == :
|
50
|
-
b1.use Call,
|
49
|
+
elsif env1[:machine].provider_config.vm_type == :lxc
|
50
|
+
b1.use Call, UploadTemplateFile do |env2, b2|
|
51
51
|
if env2[:result] == :ok
|
52
52
|
b2.use CreateVm
|
53
53
|
b2.use StartVm
|
@@ -58,6 +58,34 @@ module VagrantPlugins
|
|
58
58
|
b2.use MessageUploadServerError
|
59
59
|
end
|
60
60
|
end
|
61
|
+
elsif env1[:machine].provider_config.vm_type == :qemu
|
62
|
+
if env1[:machine].provider_config.qemu_iso
|
63
|
+
b1.use Call, UploadIsoFile do |env2, b2|
|
64
|
+
if env2[:result] == :ok
|
65
|
+
b2.use CreateVm
|
66
|
+
b2.use StartVm
|
67
|
+
b2.use SyncFolders
|
68
|
+
elsif env2[:result] == :file_not_found
|
69
|
+
b2.use MessageFileNotFound
|
70
|
+
elsif env2[:result] == :server_upload_error
|
71
|
+
b2.use MessageUploadServerError
|
72
|
+
end
|
73
|
+
end
|
74
|
+
else
|
75
|
+
b1.use CloneVm
|
76
|
+
b1.use Call, IsCreated do |env2, b2|
|
77
|
+
if env2[:result]
|
78
|
+
b2.use AdjustForwardedPortParams
|
79
|
+
b2.use ConfigClone
|
80
|
+
b2.use StartVm
|
81
|
+
b2.use SyncFolders
|
82
|
+
elsif env2[:result] == :file_not_found
|
83
|
+
b2.use MessageFileNotFound
|
84
|
+
elsif env2[:result] == :server_upload_error
|
85
|
+
b2.use MessageUploadServerError
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
61
89
|
end
|
62
90
|
end
|
63
91
|
end
|
@@ -134,6 +162,9 @@ module VagrantPlugins
|
|
134
162
|
Vagrant::Action::Builder.new.tap do |b|
|
135
163
|
b.use ConfigValidate
|
136
164
|
b.use ConnectProxmox
|
165
|
+
b.use GetNodeList
|
166
|
+
b.use SelectNode
|
167
|
+
b.use AdjustForwardedPortParams
|
137
168
|
b.use ReadSSHInfo
|
138
169
|
end
|
139
170
|
end
|
@@ -163,9 +194,9 @@ module VagrantPlugins
|
|
163
194
|
b.use Call, IsCreated do |env1, b1|
|
164
195
|
if env1[:result]
|
165
196
|
b1.use Call, IsStopped do |env2, b2|
|
166
|
-
|
197
|
+
if env2[:result]
|
167
198
|
b2.use MessageNotRunning
|
168
|
-
|
199
|
+
else
|
169
200
|
b2.use SSHRun
|
170
201
|
end
|
171
202
|
end
|
@@ -191,6 +222,9 @@ module VagrantPlugins
|
|
191
222
|
autoload :MessageFileNotFound, action_root.join('message_file_not_found')
|
192
223
|
autoload :MessageUploadServerError, action_root.join('message_upload_server_error')
|
193
224
|
autoload :CreateVm, action_root.join('create_vm')
|
225
|
+
autoload :CloneVm, action_root.join('clone_vm')
|
226
|
+
autoload :AdjustForwardedPortParams, action_root.join('adjust_forwarded_port_params')
|
227
|
+
autoload :ConfigClone, action_root.join('config_clone')
|
194
228
|
autoload :StartVm, action_root.join('start_vm')
|
195
229
|
autoload :StopVm, action_root.join('stop_vm')
|
196
230
|
autoload :ShutdownVm, action_root.join('shutdown_vm')
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Proxmox
|
3
|
+
module Action
|
4
|
+
|
5
|
+
# This action creates a new virtual machine on the Proxmox server and
|
6
|
+
# stores its node and vm_id env[:machine].id
|
7
|
+
class AdjustForwardedPortParams < ProxmoxAction
|
8
|
+
|
9
|
+
def initialize app, env
|
10
|
+
@app = app
|
11
|
+
@logger = Log4r::Logger.new 'vagrant_proxmox::action::adjust_forwarded_port_params'
|
12
|
+
end
|
13
|
+
|
14
|
+
def call env
|
15
|
+
env[:ui].info I18n.t('vagrant_proxmox.adjust_forwarded_port_params')
|
16
|
+
config = env[:machine].provider_config
|
17
|
+
node = env[:proxmox_selected_node]
|
18
|
+
vm_id = nil
|
19
|
+
|
20
|
+
begin
|
21
|
+
vm_id = env[:machine].id.split("/").last
|
22
|
+
node_ip = env[:proxmox_connection].get_node_ip(node, 'vmbr0')
|
23
|
+
env[:machine].config.vm.networks.each do |type, options|
|
24
|
+
next if type != :forwarded_port
|
25
|
+
if options[:id] == "ssh"
|
26
|
+
# Provisioning and vagrant ssh will use this
|
27
|
+
# high port of the selected proxmox node
|
28
|
+
options[:auto_correct] = false
|
29
|
+
options[:host_ip] = node_ip
|
30
|
+
options[:host] = sprintf("22%03d", vm_id.to_i).to_i
|
31
|
+
env[:machine].config.ssh.host = node_ip
|
32
|
+
env[:machine].config.ssh.port = sprintf("22%03d", vm_id.to_i).to_s
|
33
|
+
break
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
next_action env
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Proxmox
|
3
|
+
module Action
|
4
|
+
|
5
|
+
# This action clones from a qemu template on the Proxmox server and
|
6
|
+
# stores its node and vm_id env[:machine].id
|
7
|
+
class CloneVm < ProxmoxAction
|
8
|
+
|
9
|
+
def initialize app, env
|
10
|
+
@app = app
|
11
|
+
@logger = Log4r::Logger.new 'vagrant_proxmox::action::clone_vm'
|
12
|
+
end
|
13
|
+
|
14
|
+
def call env
|
15
|
+
env[:ui].info I18n.t('vagrant_proxmox.cloning_vm')
|
16
|
+
config = env[:machine].provider_config
|
17
|
+
|
18
|
+
node = env[:proxmox_selected_node]
|
19
|
+
vm_id = nil
|
20
|
+
template_vm_id = nil
|
21
|
+
|
22
|
+
begin
|
23
|
+
template_vm_id = connection(env).get_qemu_template_id(config.qemu_template)
|
24
|
+
rescue StandardError => e
|
25
|
+
raise VagrantPlugins::Proxmox::Errors::VMCloneError, proxmox_exit_status: e.message
|
26
|
+
end
|
27
|
+
|
28
|
+
begin
|
29
|
+
vm_id = connection(env).get_free_vm_id
|
30
|
+
params = create_params_qemu(config, env, vm_id, template_vm_id)
|
31
|
+
exit_status = connection(env).clone_vm node: node, vm_type: config.vm_type, params: params
|
32
|
+
exit_status == 'OK' ? exit_status : raise(VagrantPlugins::Proxmox::Errors::ProxmoxTaskFailed, proxmox_exit_status: exit_status)
|
33
|
+
rescue StandardError => e
|
34
|
+
raise VagrantPlugins::Proxmox::Errors::VMCloneError, proxmox_exit_status: e.message
|
35
|
+
end
|
36
|
+
|
37
|
+
env[:machine].id = "#{node}/#{vm_id}"
|
38
|
+
|
39
|
+
env[:ui].info I18n.t('vagrant_proxmox.done')
|
40
|
+
next_action env
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
def create_params_qemu(config, env, vm_id, template_vm_id)
|
45
|
+
# without network, which will added in ConfigClonedVm
|
46
|
+
{vmid: template_vm_id,
|
47
|
+
newid: vm_id,
|
48
|
+
name: env[:machine].config.vm.hostname || env[:machine].name.to_s,
|
49
|
+
description: "#{config.vm_name_prefix}#{env[:machine].name}"}
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Proxmox
|
3
|
+
module Action
|
4
|
+
|
5
|
+
# This action modifies the configuration of a cloned vm
|
6
|
+
# Basically it creates a user network interface with hostfwd for the provisioning
|
7
|
+
# and an interface for every public or private interface defined in the Vagrantfile
|
8
|
+
class ConfigClone < ProxmoxAction
|
9
|
+
|
10
|
+
def initialize app, env
|
11
|
+
@app = app
|
12
|
+
@logger = Log4r::Logger.new 'vagrant_proxmox::action::config_clone'
|
13
|
+
@node_ip = nil
|
14
|
+
@guest_port = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def call env
|
18
|
+
env[:ui].info I18n.t('vagrant_proxmox.configuring_vm')
|
19
|
+
config = env[:machine].provider_config
|
20
|
+
node = env[:proxmox_selected_node]
|
21
|
+
vm_id = nil
|
22
|
+
|
23
|
+
begin
|
24
|
+
vm_id = env[:machine].id.split("/").last
|
25
|
+
@node_ip = connection(env).get_node_ip(node, 'vmbr0') if config.vm_type == :qemu
|
26
|
+
@guest_port = sprintf("22%03d", vm_id.to_i).to_s
|
27
|
+
rescue StandardError => e
|
28
|
+
raise VagrantPlugins::Proxmox::Errors::VMConfigError, proxmox_exit_status: e.message
|
29
|
+
end
|
30
|
+
|
31
|
+
begin
|
32
|
+
template_config = connection(env).get_vm_config node: node, vm_id: vm_id, vm_type: config.vm_type
|
33
|
+
params = create_params_qemu(config, env, vm_id, template_config)
|
34
|
+
exit_status = connection(env).config_clone node: node, vm_type: config.vm_type, params: params
|
35
|
+
exit_status == 'OK' ? exit_status : raise(VagrantPlugins::Proxmox::Errors::ProxmoxTaskFailed, proxmox_exit_status: exit_status)
|
36
|
+
rescue StandardError => e
|
37
|
+
raise VagrantPlugins::Proxmox::Errors::VMConfigError, proxmox_exit_status: e.message
|
38
|
+
end
|
39
|
+
|
40
|
+
env[:ui].info I18n.t('vagrant_proxmox.done')
|
41
|
+
next_action env
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
def create_params_qemu(provider_config, env, vm_id, template_config)
|
46
|
+
vm_config = env[:machine].config.vm
|
47
|
+
params = {
|
48
|
+
vmid: vm_id,
|
49
|
+
description: "#{provider_config.vm_name_prefix}#{env[:machine].name}",
|
50
|
+
}
|
51
|
+
# delete existing network interfaces from template
|
52
|
+
to_delete = template_config.keys.select{|key| key.to_s.match(/^net/) }
|
53
|
+
params[:delete] = to_delete.join(",") if not to_delete.empty?
|
54
|
+
# net0 is the provisioning network, derived from forwarded_port
|
55
|
+
net_num = 0
|
56
|
+
hostname = vm_config.hostname || env[:machine].name
|
57
|
+
netdev0 = [
|
58
|
+
"type=user",
|
59
|
+
"id=net0",
|
60
|
+
"hostname=#{hostname}",
|
61
|
+
"hostfwd=tcp:#{@node_ip}:#{@guest_port}-:22", # selected_node's primary ip and port (22000 + vm_id)
|
62
|
+
]
|
63
|
+
device0 = [
|
64
|
+
"#{provider_config.qemu_nic_model}",
|
65
|
+
"netdev=net0",
|
66
|
+
"bus=pci.0",
|
67
|
+
"addr=0x12", # starting point for network interfaces
|
68
|
+
"id=net0",
|
69
|
+
"bootindex=299"
|
70
|
+
]
|
71
|
+
params[:args] = "-netdev " + netdev0.join(",") + " -device " + device0.join(",")
|
72
|
+
# now add a network device for every public_network or private_network
|
73
|
+
# ip addresses are ignored here, as we can't configure anything inside the qemu vm.
|
74
|
+
# at least we can set the predefined mac address and a bridge
|
75
|
+
net_num += 1
|
76
|
+
vm_config.networks.each do |type, options|
|
77
|
+
next if not type.match(/^p.*_network$/)
|
78
|
+
nic = provider_config.qemu_nic_model
|
79
|
+
nic += "=#{options[:macaddress]}" if options[:macaddress]
|
80
|
+
nic += ",bridge=#{options[:bridge]}" if options[:bridge]
|
81
|
+
net = 'net' + net_num.to_s
|
82
|
+
params[net] = nic
|
83
|
+
net_num += 1
|
84
|
+
end
|
85
|
+
|
86
|
+
# some more individual settings
|
87
|
+
params[:ide2] = "#{provider_config.qemu_iso},media=cdrom" if provider_config.qemu_iso
|
88
|
+
params[:sockets] = "#{provider_config.qemu_sockets}".to_i if provider_config.qemu_sockets
|
89
|
+
params[:cores] = "#{provider_config.qemu_cores}".to_i if provider_config.qemu_cores
|
90
|
+
params[:balloon] = "#{provider_config.vm_memory}".to_i if provider_config.vm_memory and provider_config.vm_memory < template_config[:balloon]
|
91
|
+
params[:memory] = "#{provider_config.vm_memory}".to_i if provider_config.vm_memory
|
92
|
+
params
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -21,6 +21,7 @@ module VagrantPlugins
|
|
21
21
|
begin
|
22
22
|
vm_id = connection(env).get_free_vm_id
|
23
23
|
params = create_params_openvz(config, env, vm_id) if config.vm_type == :openvz
|
24
|
+
params = create_params_lxc(config, env, vm_id) if config.vm_type == :lxc
|
24
25
|
params = create_params_qemu(config, env, vm_id) if config.vm_type == :qemu
|
25
26
|
exit_status = connection(env).create_vm node: node, vm_type: config.vm_type, params: params
|
26
27
|
exit_status == 'OK' ? exit_status : raise(VagrantPlugins::Proxmox::Errors::ProxmoxTaskFailed, proxmox_exit_status: exit_status)
|
@@ -62,6 +63,20 @@ module VagrantPlugins
|
|
62
63
|
params[:ip_address] = get_machine_ip_address(env) if get_machine_ip_address(env)
|
63
64
|
end
|
64
65
|
end
|
66
|
+
|
67
|
+
private
|
68
|
+
def create_params_lxc(config, env, vm_id)
|
69
|
+
{vmid: vm_id,
|
70
|
+
ostemplate: config.openvz_os_template,
|
71
|
+
hostname: env[:machine].config.vm.hostname || env[:machine].name.to_s,
|
72
|
+
password: 'vagrant',
|
73
|
+
storage: "#{config.vm_storage}:#{config.vm_disk_size}",
|
74
|
+
memory: config.vm_memory,
|
75
|
+
description: "#{config.vm_name_prefix}#{env[:machine].name}"}
|
76
|
+
.tap do |params|
|
77
|
+
params[:net0] = "name=#{get_machine_interface_name(env)},ip=#{get_machine_ip_address(env)}/24,gw=#{get_machine_gw_ip(env)},bridge=#{get_machine_bridge_name(env)}" if get_machine_ip_address(env)
|
78
|
+
end
|
79
|
+
end
|
65
80
|
end
|
66
81
|
end
|
67
82
|
end
|
@@ -11,8 +11,28 @@ module VagrantPlugins
|
|
11
11
|
|
12
12
|
protected
|
13
13
|
def get_machine_ip_address env
|
14
|
-
env[:machine].
|
14
|
+
config = env[:machine].provider_config
|
15
|
+
if config.vm_type == :qemu
|
16
|
+
env[:machine].config.vm.networks.select { |type, _| type == :forwarded_port }.first[1][:host_ip] rescue nil
|
17
|
+
else
|
18
|
+
env[:machine].config.vm.networks.select { |type, _| type == :public_network }.first[1][:ip] rescue nil
|
19
|
+
end
|
15
20
|
end
|
21
|
+
|
22
|
+
protected
|
23
|
+
def get_machine_interface_name env
|
24
|
+
env[:machine].config.vm.networks.select { |type, _| type == :public_network }.first[1][:interface] rescue nil
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
def get_machine_bridge_name env
|
29
|
+
env[:machine].config.vm.networks.select { |type, _| type == :public_network }.first[1][:bridge] rescue nil
|
30
|
+
end
|
31
|
+
|
32
|
+
protected
|
33
|
+
def get_machine_gw_ip env
|
34
|
+
env[:machine].config.vm.networks.select { |type, _| type == :public_network }.first[1][:gw] rescue nil
|
35
|
+
end
|
16
36
|
|
17
37
|
protected
|
18
38
|
def get_machine_macaddress env
|
@@ -7,12 +7,14 @@ module VagrantPlugins
|
|
7
7
|
|
8
8
|
def initialize app, env
|
9
9
|
@app = app
|
10
|
+
@logger = Log4r::Logger.new 'vagrant_proxmox::action::read_ssh_info'
|
10
11
|
end
|
11
12
|
|
12
13
|
def call env
|
13
14
|
env[:machine_ssh_info] = get_machine_ip_address(env).try do |ip_address|
|
14
15
|
{host: ip_address, port: env[:machine].config.ssh.guest_port}
|
15
16
|
end
|
17
|
+
env[:machine_ssh_info]
|
16
18
|
next_action env
|
17
19
|
end
|
18
20
|
|
@@ -22,7 +22,7 @@ module VagrantPlugins
|
|
22
22
|
# @return [String]
|
23
23
|
attr_accessor :password
|
24
24
|
|
25
|
-
# The virtual machine type, e.g. :openvz or :qemu
|
25
|
+
# The virtual machine type, e.g. :openvz or :qemu or :lxc
|
26
26
|
#
|
27
27
|
# @return [Symbol]
|
28
28
|
attr_accessor :vm_type
|
@@ -57,6 +57,17 @@ module VagrantPlugins
|
|
57
57
|
# @return [Integer]
|
58
58
|
attr_accessor :vm_memory
|
59
59
|
|
60
|
+
# The vm disk size to use for the virtual machine, e.g. '30G'
|
61
|
+
#
|
62
|
+
# @return [String]
|
63
|
+
attr_accessor :vm_disk_size
|
64
|
+
|
65
|
+
# The vm storage to use for the virtual machine, e.g. 'local', 'raid', 'cephstore'
|
66
|
+
# defaults to 'raid' for backwards compatability
|
67
|
+
#
|
68
|
+
# @return [String]
|
69
|
+
attr_accessor :vm_storage
|
70
|
+
|
60
71
|
# The maximum timeout for a proxmox server task (in seconds)
|
61
72
|
#
|
62
73
|
# @return [Integer]
|
@@ -97,6 +108,11 @@ module VagrantPlugins
|
|
97
108
|
# @return [Integer]
|
98
109
|
attr_accessor :qemu_sockets
|
99
110
|
|
111
|
+
# The qemu template to clone for the virtual machine
|
112
|
+
#
|
113
|
+
# @return [String]
|
114
|
+
attr_accessor :qemu_template
|
115
|
+
|
100
116
|
# The qemu iso file to use for the virtual machine
|
101
117
|
#
|
102
118
|
# @return [String]
|
@@ -147,6 +163,8 @@ module VagrantPlugins
|
|
147
163
|
@vm_id_range = 900..999
|
148
164
|
@vm_name_prefix = 'vagrant_'
|
149
165
|
@vm_memory = 512
|
166
|
+
@vm_disk_size = '20G'
|
167
|
+
@vm_storage = 'local'
|
150
168
|
@task_timeout = 60
|
151
169
|
@task_status_check_interval = 2
|
152
170
|
@ssh_timeout = 60
|
@@ -155,6 +173,7 @@ module VagrantPlugins
|
|
155
173
|
@qemu_os = UNSET_VALUE
|
156
174
|
@qemu_cores = 1
|
157
175
|
@qemu_sockets = 1
|
176
|
+
@qemu_template = UNSET_VALUE
|
158
177
|
@qemu_iso = UNSET_VALUE
|
159
178
|
@qemu_iso_file = UNSET_VALUE
|
160
179
|
@replace_qemu_iso_file = false
|
@@ -174,12 +193,14 @@ module VagrantPlugins
|
|
174
193
|
@openvz_template_file = nil if @openvz_template_file == UNSET_VALUE
|
175
194
|
@openvz_os_template = "local:vztmpl/#{File.basename @openvz_template_file}" if @openvz_template_file
|
176
195
|
@openvz_os_template = nil if @openvz_os_template == UNSET_VALUE
|
196
|
+
@qemu_template = nil if @qemu_os == UNSET_VALUE
|
177
197
|
@qemu_os = nil if @qemu_os == UNSET_VALUE
|
178
198
|
@qemu_iso_file = nil if @qemu_iso_file == UNSET_VALUE
|
179
199
|
@qemu_iso = "local:iso/#{File.basename @qemu_iso_file}" if @qemu_iso_file
|
180
200
|
@qemu_iso = nil if @qemu_iso == UNSET_VALUE
|
181
201
|
@qemu_disk_size = nil if @qemu_disk_size == UNSET_VALUE
|
182
202
|
@qemu_disk_size = convert_disk_size_to_gigabyte @qemu_disk_size if @qemu_disk_size
|
203
|
+
@vm_disk_size = convert_disk_size_to_gigabyte @vm_disk_size if @vm_disk_size
|
183
204
|
end
|
184
205
|
|
185
206
|
def validate machine
|
@@ -192,9 +213,12 @@ module VagrantPlugins
|
|
192
213
|
errors << I18n.t('vagrant_proxmox.errors.no_openvz_os_template_or_openvz_template_file_specified_for_type_openvz') unless @openvz_os_template || @openvz_template_file
|
193
214
|
end
|
194
215
|
if @vm_type == :qemu
|
195
|
-
|
196
|
-
|
197
|
-
|
216
|
+
if @qemu_template
|
217
|
+
else
|
218
|
+
errors << I18n.t('vagrant_proxmox.errors.no_qemu_os_specified_for_vm_type_qemu') unless @qemu_os
|
219
|
+
errors << I18n.t('vagrant_proxmox.errors.no_qemu_iso_or_qemu_iso_file_specified_for_vm_type_qemu') unless @qemu_iso || @qemu_iso_file
|
220
|
+
errors << I18n.t('vagrant_proxmox.errors.no_qemu_disk_size_specified_for_vm_type_qemu') unless @qemu_disk_size
|
221
|
+
end
|
198
222
|
end
|
199
223
|
{'Proxmox Provider' => errors}
|
200
224
|
end
|
@@ -30,6 +30,18 @@ module VagrantPlugins
|
|
30
30
|
error_key :vm_create_error
|
31
31
|
end
|
32
32
|
|
33
|
+
class VMCloneError < VagrantProxmoxError
|
34
|
+
error_key :vm_clone_error
|
35
|
+
end
|
36
|
+
|
37
|
+
class NoTemplateAvailable < VagrantProxmoxError
|
38
|
+
error_key :no_template_available
|
39
|
+
end
|
40
|
+
|
41
|
+
class VMConfigError < VagrantProxmoxError
|
42
|
+
error_key :vm_configure_error
|
43
|
+
end
|
44
|
+
|
33
45
|
class VMDestroyError < VagrantProxmoxError
|
34
46
|
error_key :vm_destroy_error
|
35
47
|
end
|
@@ -100,6 +100,34 @@ module VagrantPlugins
|
|
100
100
|
wait_for_completion task_response: response, timeout_message: 'vagrant_proxmox.errors.create_vm_timeout'
|
101
101
|
end
|
102
102
|
|
103
|
+
def clone_vm node: required('node'), vm_type: required('node'), params: required('params')
|
104
|
+
vm_id = params[:vmid]
|
105
|
+
params.delete(:vmid)
|
106
|
+
params.delete(:ostype)
|
107
|
+
params.delete(:ide2)
|
108
|
+
params.delete(:sata0)
|
109
|
+
params.delete(:sockets)
|
110
|
+
params.delete(:cores)
|
111
|
+
params.delete(:description)
|
112
|
+
params.delete(:memory)
|
113
|
+
params.delete(:net0)
|
114
|
+
response = post "/nodes/#{node}/#{vm_type}/#{vm_id}/clone", params
|
115
|
+
wait_for_completion task_response: response, timeout_message: 'vagrant_proxmox.errors.create_vm_timeout'
|
116
|
+
end
|
117
|
+
|
118
|
+
def config_clone node: required('node'), vm_type: required('node'), params: required('params')
|
119
|
+
vm_id = params[:vmid]
|
120
|
+
params.delete(:vmid)
|
121
|
+
response = post "/nodes/#{node}/#{vm_type}/#{vm_id}/config", params
|
122
|
+
wait_for_completion task_response: response, timeout_message: 'vagrant_proxmox.errors.create_vm_timeout'
|
123
|
+
end
|
124
|
+
|
125
|
+
def get_vm_config node: required('node'), vm_id: required('node'), vm_type: required('node')
|
126
|
+
response = get "/nodes/#{node}/#{vm_type}/#{vm_id}/config"
|
127
|
+
response = response[:data]
|
128
|
+
response.empty? ? raise(VagrantPlugins::Proxmox::Errors::VMConfigError) : response
|
129
|
+
end
|
130
|
+
|
103
131
|
def start_vm vm_id
|
104
132
|
vm_info = get_vm_info vm_id
|
105
133
|
response = post "/nodes/#{vm_info[:node]}/#{vm_info[:type]}/#{vm_id}/status/start", nil
|
@@ -119,6 +147,8 @@ module VagrantPlugins
|
|
119
147
|
end
|
120
148
|
|
121
149
|
def get_free_vm_id
|
150
|
+
# to avoid collisions in multi-vm setups
|
151
|
+
sleep (rand(1..3) + 0.1 * rand(0..9))
|
122
152
|
response = get "/cluster/resources?type=vm"
|
123
153
|
allowed_vm_ids = vm_id_range.to_set
|
124
154
|
used_vm_ids = response[:data].map { |vm| vm[:vmid] }
|
@@ -126,6 +156,12 @@ module VagrantPlugins
|
|
126
156
|
free_vm_ids.empty? ? raise(VagrantPlugins::Proxmox::Errors::NoVmIdAvailable) : free_vm_ids.first
|
127
157
|
end
|
128
158
|
|
159
|
+
def get_qemu_template_id template
|
160
|
+
response = get "/cluster/resources?type=vm"
|
161
|
+
found_ids = response[:data].select { |vm| vm[:type] == 'qemu' }.select { |vm| vm[:template] == 1 }.select { |vm| vm[:name] == template }.map { |vm| vm[:vmid] }
|
162
|
+
found_ids.empty? ? raise(VagrantPlugins::Proxmox::Errors::NoTemplateAvailable) : found_ids.first
|
163
|
+
end
|
164
|
+
|
129
165
|
def upload_file file, content_type: required('content_type'), node: required('node'), storage: required('storage'), replace: false
|
130
166
|
delete_file(filename: file, content_type: content_type, node: node, storage: storage) if replace
|
131
167
|
unless is_file_in_storage? filename: file, node: node, storage: storage
|
@@ -144,6 +180,15 @@ module VagrantPlugins
|
|
144
180
|
res[:data].map { |e| e[:volid] }
|
145
181
|
end
|
146
182
|
|
183
|
+
def get_node_ip node, interface
|
184
|
+
begin
|
185
|
+
response = get "/nodes/#{node}/network/#{interface}"
|
186
|
+
response[:data][:address]
|
187
|
+
rescue ApiError::ServerError
|
188
|
+
:not_created
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
147
192
|
# This is called every time to retrieve the node and vm_type, hence on large
|
148
193
|
# installations this could be a huge amount of data. Probably an optimization
|
149
194
|
# with a buffer for the machine info could be considered.
|
@@ -222,4 +267,5 @@ module VagrantPlugins
|
|
222
267
|
end
|
223
268
|
end
|
224
269
|
end
|
225
|
-
end
|
270
|
+
end
|
271
|
+
|
data/spec/provider_spec.rb
CHANGED
@@ -3,23 +3,26 @@ require 'vagrant-proxmox/provider'
|
|
3
3
|
|
4
4
|
module VagrantPlugins::Proxmox
|
5
5
|
|
6
|
-
|
6
|
+
describe Provider do
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
let(:machine) { environment.machine(environment.primary_machine_name, :proxmox) }
|
9
|
+
let(:environment) { Vagrant::Environment.new vagrantfile_name: 'dummy_box/Vagrantfile' }
|
10
|
+
let(:ui) { double('ui').as_null_object }
|
11
11
|
|
12
|
-
|
12
|
+
subject { described_class.new(machine) }
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
14
|
+
describe '#ssh_info', :need_box do
|
15
|
+
it 'should call the appropriate actions and return the ssh info' do
|
16
|
+
expect(Action::ConfigValidate).to be_called
|
17
|
+
expect(Action::ConnectProxmox).to be_called
|
18
|
+
expect(Action::GetNodeList).to be_called
|
19
|
+
expect(Action::SelectNode).to be_called
|
20
|
+
expect(Action::AdjustForwardedPortParams).to be_called
|
21
|
+
expect(Action::ReadSSHInfo).to be_called { |env| env[:machine_ssh_info] = 'ssh_info' }
|
22
|
+
expect(subject.ssh_info).to eq('ssh_info')
|
23
|
+
end
|
24
|
+
end
|
22
25
|
|
23
|
-
|
26
|
+
end
|
24
27
|
|
25
28
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vagrant-proxmox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dirk Grappendorf
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2016-03-29 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rest-client
|
@@ -58,16 +58,16 @@ dependencies:
|
|
58
58
|
name: rake
|
59
59
|
requirement: !ruby/object:Gem::Requirement
|
60
60
|
requirements:
|
61
|
-
- -
|
61
|
+
- - '='
|
62
62
|
- !ruby/object:Gem::Version
|
63
|
-
version:
|
63
|
+
version: 10.5.0
|
64
64
|
type: :development
|
65
65
|
prerelease: false
|
66
66
|
version_requirements: !ruby/object:Gem::Requirement
|
67
67
|
requirements:
|
68
|
-
- -
|
68
|
+
- - '='
|
69
69
|
- !ruby/object:Gem::Version
|
70
|
-
version:
|
70
|
+
version: 10.5.0
|
71
71
|
- !ruby/object:Gem::Dependency
|
72
72
|
name: rspec
|
73
73
|
requirement: !ruby/object:Gem::Requirement
|
@@ -221,7 +221,10 @@ files:
|
|
221
221
|
- lib/sanity_checks.rb
|
222
222
|
- lib/vagrant-proxmox.rb
|
223
223
|
- lib/vagrant-proxmox/action.rb
|
224
|
+
- lib/vagrant-proxmox/action/adjust_forwarded_port_params.rb
|
224
225
|
- lib/vagrant-proxmox/action/cleanup_after_destroy.rb
|
226
|
+
- lib/vagrant-proxmox/action/clone_vm.rb
|
227
|
+
- lib/vagrant-proxmox/action/config_clone.rb
|
225
228
|
- lib/vagrant-proxmox/action/connect_proxmox.rb
|
226
229
|
- lib/vagrant-proxmox/action/create_vm.rb
|
227
230
|
- lib/vagrant-proxmox/action/destroy_vm.rb
|
@@ -312,48 +315,48 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
312
315
|
version: '0'
|
313
316
|
requirements: []
|
314
317
|
rubyforge_project:
|
315
|
-
rubygems_version: 2.4.
|
318
|
+
rubygems_version: 2.4.8
|
316
319
|
signing_key:
|
317
320
|
specification_version: 4
|
318
321
|
summary: Enables Vagrant to manage virtual machines on a Proxmox server.
|
319
322
|
test_files:
|
320
|
-
- spec/
|
321
|
-
- spec/
|
322
|
-
- spec/
|
323
|
+
- spec/config_spec.rb
|
324
|
+
- spec/spec_helpers/time_helpers.rb
|
325
|
+
- spec/spec_helpers/common_helpers.rb
|
326
|
+
- spec/actions/is_created_action_spec.rb
|
323
327
|
- spec/actions/proxmox_action_shared.rb
|
324
|
-
- spec/actions/sync_folders_action_spec.rb
|
325
|
-
- spec/actions/connect_proxmox_action_spec.rb
|
326
|
-
- spec/actions/cleanup_after_destroy_action_spec.rb
|
327
|
-
- spec/actions/is_stopped_action_spec.rb
|
328
328
|
- spec/actions/read_ssh_info_action_spec.rb
|
329
|
-
- spec/actions/create_vm_action_spec.rb
|
330
|
-
- spec/actions/proxmox_action_spec.rb
|
331
329
|
- spec/actions/shutdown_vm_action_spec.rb
|
332
|
-
- spec/actions/
|
333
|
-
- spec/actions/
|
330
|
+
- spec/actions/destroy_vm_action_spec.rb
|
331
|
+
- spec/actions/cleanup_after_destroy_action_spec.rb
|
332
|
+
- spec/actions/select_node_spec.rb
|
334
333
|
- spec/actions/stop_vm_action_spec.rb
|
334
|
+
- spec/actions/message_file_not_found_spec.rb
|
335
|
+
- spec/actions/read_state_action_spec.rb
|
336
|
+
- spec/actions/message_not_created_action_spec.rb
|
337
|
+
- spec/actions/create_vm_action_spec.rb
|
338
|
+
- spec/actions/start_vm_action_spec.rb
|
339
|
+
- spec/actions/message_already_running_action_spec.rb
|
340
|
+
- spec/actions/connect_proxmox_action_spec.rb
|
341
|
+
- spec/actions/get_node_list_action_spec.rb
|
335
342
|
- spec/actions/upload_template_file_action_spec.rb
|
336
|
-
- spec/actions/
|
343
|
+
- spec/actions/message_not_running_action_spec.rb
|
344
|
+
- spec/actions/proxmox_action_spec.rb
|
337
345
|
- spec/actions/upload_iso_file_action_spec.rb
|
338
|
-
- spec/actions/
|
346
|
+
- spec/actions/sync_folders_action_spec.rb
|
347
|
+
- spec/actions/is_stopped_action_spec.rb
|
348
|
+
- spec/actions/message_already_stopped_action_spec.rb
|
339
349
|
- spec/actions/message_upload_server_error_spec.rb
|
340
|
-
- spec/actions/message_not_running_action_spec.rb
|
341
|
-
- spec/actions/get_node_list_action_spec.rb
|
342
|
-
- spec/actions/message_file_not_found_spec.rb
|
343
|
-
- spec/actions/is_created_action_spec.rb
|
344
|
-
- spec/plugin_spec.rb
|
345
|
-
- spec/spec_helper.rb
|
346
|
-
- spec/sanity_checks_spec.rb
|
347
|
-
- spec/proxmox/connection_spec.rb
|
348
|
-
- spec/proxmox/rest_call_shared.rb
|
349
|
-
- spec/commands/ssh_command_spec.rb
|
350
|
-
- spec/commands/provision_command_spec.rb
|
351
350
|
- spec/commands/up_command_spec.rb
|
352
|
-
- spec/commands/destroy_command_spec.rb
|
353
|
-
- spec/commands/ssh_run_command_spec.rb
|
354
351
|
- spec/commands/halt_command_spec.rb
|
352
|
+
- spec/commands/provision_command_spec.rb
|
353
|
+
- spec/commands/ssh_run_command_spec.rb
|
354
|
+
- spec/commands/destroy_command_spec.rb
|
355
|
+
- spec/commands/ssh_command_spec.rb
|
355
356
|
- spec/commands/status_command_spec.rb
|
356
|
-
- spec/
|
357
|
+
- spec/sanity_checks_spec.rb
|
358
|
+
- spec/spec_helper.rb
|
359
|
+
- spec/proxmox/connection_spec.rb
|
360
|
+
- spec/proxmox/rest_call_shared.rb
|
361
|
+
- spec/plugin_spec.rb
|
357
362
|
- spec/provider_spec.rb
|
358
|
-
- spec/spec_helpers/time_helpers.rb
|
359
|
-
- spec/spec_helpers/common_helpers.rb
|