vagrant-proxmox 0.0.2
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 +7 -0
- data/lib/sanity_checks.rb +11 -0
- data/lib/vagrant-proxmox/action/cleanup_after_destroy.rb +20 -0
- data/lib/vagrant-proxmox/action/connect_proxmox.rb +33 -0
- data/lib/vagrant-proxmox/action/create_vm.rb +63 -0
- data/lib/vagrant-proxmox/action/destroy_vm.rb +29 -0
- data/lib/vagrant-proxmox/action/get_node_list.rb +24 -0
- data/lib/vagrant-proxmox/action/is_created.rb +20 -0
- data/lib/vagrant-proxmox/action/is_stopped.rb +20 -0
- data/lib/vagrant-proxmox/action/message_already_running.rb +20 -0
- data/lib/vagrant-proxmox/action/message_already_stopped.rb +20 -0
- data/lib/vagrant-proxmox/action/message_not_created.rb +20 -0
- data/lib/vagrant-proxmox/action/proxmox_action.rb +47 -0
- data/lib/vagrant-proxmox/action/read_ssh_info.rb +22 -0
- data/lib/vagrant-proxmox/action/read_state.rb +37 -0
- data/lib/vagrant-proxmox/action/shutdown_vm.rb +31 -0
- data/lib/vagrant-proxmox/action/start_vm.rb +40 -0
- data/lib/vagrant-proxmox/action/stop_vm.rb +31 -0
- data/lib/vagrant-proxmox/action/sync_folders.rb +52 -0
- data/lib/vagrant-proxmox/action.rb +159 -0
- data/lib/vagrant-proxmox/config.rb +81 -0
- data/lib/vagrant-proxmox/errors.rb +39 -0
- data/lib/vagrant-proxmox/plugin.rb +75 -0
- data/lib/vagrant-proxmox/provider.rb +51 -0
- data/lib/vagrant-proxmox/version.rb +7 -0
- data/lib/vagrant-proxmox.rb +22 -0
- data/locales/en.yml +66 -0
- data/spec/actions/cleanup_after_destroy_action_spec.rb +22 -0
- data/spec/actions/connect_proxmox_action_spec.rb +49 -0
- data/spec/actions/create_vm_action_spec.rb +167 -0
- data/spec/actions/destroy_vm_action_spec.rb +37 -0
- data/spec/actions/get_node_list_action_spec.rb +25 -0
- data/spec/actions/is_created_action_spec.rb +35 -0
- data/spec/actions/is_stopped_action_spec.rb +34 -0
- data/spec/actions/message_already_running_action_spec.rb +23 -0
- data/spec/actions/message_already_stopped_action_spec.rb +23 -0
- data/spec/actions/message_not_created_action_spec.rb +23 -0
- data/spec/actions/proxmox_action_shared.rb +74 -0
- data/spec/actions/read_ssh_info_action_spec.rb +32 -0
- data/spec/actions/read_state_action_spec.rb +54 -0
- data/spec/actions/shutdown_vm_action_spec.rb +37 -0
- data/spec/actions/start_vm_action_spec.rb +47 -0
- data/spec/actions/stop_vm_action_spec.rb +37 -0
- data/spec/actions/sync_folders_action_spec.rb +51 -0
- data/spec/commands/destroy_command_spec.rb +68 -0
- data/spec/commands/halt_command_spec.rb +46 -0
- data/spec/commands/provision_command_spec.rb +33 -0
- data/spec/commands/ssh_command_spec.rb +31 -0
- data/spec/commands/ssh_run_command_spec.rb +32 -0
- data/spec/commands/status_command_spec.rb +19 -0
- data/spec/commands/up_command_spec.rb +55 -0
- data/spec/config_spec.rb +71 -0
- data/spec/plugin_spec.rb +22 -0
- data/spec/provider_spec.rb +25 -0
- data/spec/sanity_checks_spec.rb +19 -0
- data/spec/spec_helper.rb +128 -0
- metadata +242 -0
@@ -0,0 +1,167 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'actions/proxmox_action_shared'
|
3
|
+
|
4
|
+
describe VagrantPlugins::Proxmox::Action::CreateVm do
|
5
|
+
|
6
|
+
it_behaves_like VagrantPlugins::Proxmox::Action::ProxmoxAction
|
7
|
+
|
8
|
+
let(:environment) { Vagrant::Environment.new vagrantfile_name: 'dummy_box/Vagrantfile' }
|
9
|
+
let(:env) { {machine: environment.machine(environment.primary_machine_name, :proxmox),
|
10
|
+
proxmox_nodes: [{node: 'localhost'}],
|
11
|
+
ui: double('ui').as_null_object} }
|
12
|
+
let(:app) { double('app').as_null_object }
|
13
|
+
let(:task_upid) { 'UPID:localhost:0000F6ED:00F8E25F:5268CD3B:vzcreate:100:vagrant@pve:' }
|
14
|
+
|
15
|
+
subject { described_class.new(app, environment) }
|
16
|
+
|
17
|
+
describe '#call' do
|
18
|
+
|
19
|
+
before do
|
20
|
+
allow(RestClient).to receive(:post).and_return({data: task_upid}.to_json)
|
21
|
+
allow(subject).to receive(:get_free_vm_id).with(env).and_return(100)
|
22
|
+
allow(subject).to receive(:wait_for_completion).and_return('OK')
|
23
|
+
end
|
24
|
+
|
25
|
+
it_behaves_like 'a proxmox action call'
|
26
|
+
it_behaves_like 'a blocking proxmox action'
|
27
|
+
|
28
|
+
describe 'the post request send to create a new virtual machine' do
|
29
|
+
|
30
|
+
context 'with default config' do
|
31
|
+
specify do
|
32
|
+
RestClient.should_receive(:post).
|
33
|
+
with('https://your.proxmox.server/api2/json/nodes/localhost/openvz',
|
34
|
+
{vmid: 100,
|
35
|
+
hostname: 'box',
|
36
|
+
ostemplate: 'local:vztmpl/template.tgz',
|
37
|
+
password: 'vagrant',
|
38
|
+
memory: 256,
|
39
|
+
description: 'vagrant_test_box'},
|
40
|
+
anything).
|
41
|
+
and_return({data: task_upid}.to_json)
|
42
|
+
subject.call env
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'with a specified hostname' do
|
47
|
+
before { env[:machine].config.vm.hostname = 'hostname' }
|
48
|
+
specify do
|
49
|
+
RestClient.should_receive(:post).
|
50
|
+
with('https://your.proxmox.server/api2/json/nodes/localhost/openvz',
|
51
|
+
{vmid: 100,
|
52
|
+
hostname: 'hostname',
|
53
|
+
ostemplate: 'local:vztmpl/template.tgz',
|
54
|
+
password: 'vagrant',
|
55
|
+
memory: 256,
|
56
|
+
description: 'vagrant_test_box'},
|
57
|
+
anything).
|
58
|
+
and_return({data: task_upid}.to_json)
|
59
|
+
subject.call env
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'with a specified ip address' do
|
64
|
+
before { env[:machine].config.vm.stub(:networks) { [[:public_network, {ip: '127.0.0.1'}]] } }
|
65
|
+
specify do
|
66
|
+
RestClient.should_receive(:post).
|
67
|
+
with('https://your.proxmox.server/api2/json/nodes/localhost/openvz',
|
68
|
+
{vmid: 100,
|
69
|
+
hostname: 'box',
|
70
|
+
ip_address: '127.0.0.1',
|
71
|
+
ostemplate: 'local:vztmpl/template.tgz',
|
72
|
+
password: 'vagrant',
|
73
|
+
memory: 256,
|
74
|
+
description: 'vagrant_test_box'},
|
75
|
+
anything).
|
76
|
+
and_return({data: task_upid}.to_json)
|
77
|
+
subject.call env
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'should print a message to the user interface' do
|
84
|
+
env[:ui].should_receive(:info).with 'Creating the virtual machine...'
|
85
|
+
env[:ui].should_receive(:info).with 'Done!'
|
86
|
+
subject.call env
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should store the node and vmid in env[:machine].id' do
|
90
|
+
subject.call env
|
91
|
+
env[:machine].id.should == 'localhost/100'
|
92
|
+
end
|
93
|
+
|
94
|
+
context 'when the proxmox server responds with an error to the create request' do
|
95
|
+
|
96
|
+
let(:error_exit_status) { ["can't lock container 100", "close (rename) atomic file '/etc/pve/nodes/localhost/openvz/100.conf' failed: File exists"] }
|
97
|
+
|
98
|
+
before { subject.stub :sleep }
|
99
|
+
|
100
|
+
context 'when the proxmox server replies with an exit status describing the error' do
|
101
|
+
it 'should create a virtual machine with another vmid' do
|
102
|
+
expect(subject).to receive(:get_free_vm_id).with(env).twice.and_return(100, 101)
|
103
|
+
expect(subject).to receive(:wait_for_completion).twice.and_return(error_exit_status.sample, 'OK')
|
104
|
+
subject.call env
|
105
|
+
env[:machine].id.should == 'localhost/101'
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context 'when the proxmox server replies with a "500 Internal Server Error"' do
|
110
|
+
it 'should create a virtual machine with another vmid' do
|
111
|
+
expect(subject).to receive(:get_free_vm_id).with(env).twice.and_return(100, 101)
|
112
|
+
expect(subject).to receive(:wait_for_completion).and_raise(RestClient::InternalServerError).once
|
113
|
+
expect(subject).to receive(:wait_for_completion).once.and_return('OK')
|
114
|
+
subject.call env
|
115
|
+
env[:machine].id.should == 'localhost/101'
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context 'when the create requests fail continuously before the timeout deadline is reached' do
|
120
|
+
it 'should raise a VMCreationError' do
|
121
|
+
expect(subject).to receive(:get_free_vm_id).with(env).exactly(30).times.and_return(100)
|
122
|
+
expect(subject).to receive(:wait_for_completion).exactly(30).times.and_return(error_exit_status.sample)
|
123
|
+
expect { subject.send :call, env }.to raise_error VagrantPlugins::Proxmox::Errors::VMCreationError
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
describe '#get_free_vm_id' do
|
132
|
+
|
133
|
+
it 'should query the proxmox server for all qemu and openvz machines' do
|
134
|
+
RestClient.should_receive(:get).with('https://your.proxmox.server/api2/json/cluster/resources?type=vm', anything).and_return({data: []}.to_json)
|
135
|
+
subject.send(:get_free_vm_id, env)
|
136
|
+
end
|
137
|
+
|
138
|
+
describe 'find the smallest unused vm_id in the configured range' do
|
139
|
+
|
140
|
+
before { env[:machine].provider_config.vm_id_range = 3..4 }
|
141
|
+
|
142
|
+
context 'when free vm_ids are available' do
|
143
|
+
[
|
144
|
+
{used_vm_ids: {data: []}, smallest_free_in_range: 3},
|
145
|
+
{used_vm_ids: {data: [{vmid: 3}]}, smallest_free_in_range: 4},
|
146
|
+
{used_vm_ids: {data: [{vmid: 1}]}, smallest_free_in_range: 3},
|
147
|
+
{used_vm_ids: {data: [{vmid: 1}, {vmid: 3}]}, smallest_free_in_range: 4},
|
148
|
+
].each do |example|
|
149
|
+
it 'should return the smallest unused vm_id in the configured vm_id_range' do
|
150
|
+
allow(RestClient).to receive(:get).and_return(example[:used_vm_ids].to_json)
|
151
|
+
subject.send(:get_free_vm_id, env).should == example[:smallest_free_in_range]
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context 'when no vm_ids are available' do
|
157
|
+
it 'should throw a no_vm_id_available error' do
|
158
|
+
allow(RestClient).to receive(:get).and_return({data: [{vmid: 1}, {vmid: 2}, {vmid: 3}, {vmid: 4}]}.to_json)
|
159
|
+
expect { subject.send :get_free_vm_id, env }.to raise_error VagrantPlugins::Proxmox::Errors::NoVmIdAvailable
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'actions/proxmox_action_shared'
|
3
|
+
|
4
|
+
describe VagrantPlugins::Proxmox::Action::DestroyVm do
|
5
|
+
|
6
|
+
let(:environment) { Vagrant::Environment.new vagrantfile_name: 'dummy_box/Vagrantfile' }
|
7
|
+
let(:env) { {machine: environment.machine(environment.primary_machine_name, :proxmox),
|
8
|
+
proxmox_nodes: [{node: 'localhost'}],
|
9
|
+
ui: double('ui').as_null_object} }
|
10
|
+
|
11
|
+
subject { described_class.new(-> (_) {}, environment) }
|
12
|
+
|
13
|
+
describe '#call' do
|
14
|
+
|
15
|
+
before do
|
16
|
+
env[:machine].id = 'localhost/100'
|
17
|
+
allow(RestClient).to receive(:delete).and_return({data: 'task_id'}.to_json)
|
18
|
+
allow(RestClient).to receive(:get).and_return({data: {exitstatus: 'OK'}}.to_json)
|
19
|
+
end
|
20
|
+
|
21
|
+
it_behaves_like 'a proxmox action call'
|
22
|
+
it_behaves_like 'a blocking proxmox action'
|
23
|
+
|
24
|
+
it 'should send a post request that deletes the openvz container' do
|
25
|
+
RestClient.should_receive(:delete).with('https://your.proxmox.server/api2/json/nodes/localhost/openvz/100', anything)
|
26
|
+
subject.call env
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should print a message to the user interface' do
|
30
|
+
env[:ui].should_receive(:info).with 'Destroying the virtual machine...'
|
31
|
+
env[:ui].should_receive(:info).with 'Done!'
|
32
|
+
subject.call env
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'actions/proxmox_action_shared'
|
3
|
+
|
4
|
+
describe VagrantPlugins::Proxmox::Action::GetNodeList do
|
5
|
+
|
6
|
+
let(:environment) { Vagrant::Environment.new vagrantfile_name: 'dummy_box/Vagrantfile' }
|
7
|
+
let(:env) { {machine: environment.machine(environment.primary_machine_name, :proxmox)} }
|
8
|
+
|
9
|
+
subject { described_class.new(-> (_) {}, environment) }
|
10
|
+
|
11
|
+
describe '#call' do
|
12
|
+
|
13
|
+
before {allow(RestClient).to receive(:get).and_return({data: [{node: 'localhost'}]}.to_json)}
|
14
|
+
|
15
|
+
it_behaves_like 'a proxmox action call'
|
16
|
+
|
17
|
+
it 'should store the node list in env[:proxmox_nodes]' do
|
18
|
+
RestClient.should_receive(:get).with('https://your.proxmox.server/api2/json/nodes', anything)
|
19
|
+
subject.call env
|
20
|
+
env[:proxmox_nodes].should == [{node: 'localhost'}]
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'actions/proxmox_action_shared'
|
3
|
+
|
4
|
+
describe VagrantPlugins::Proxmox::Action::IsCreated do
|
5
|
+
|
6
|
+
let(:environment) { Vagrant::Environment.new vagrantfile_name: 'dummy_box/Vagrantfile' }
|
7
|
+
let(:env) { {machine: environment.machine(environment.primary_machine_name, :proxmox)} }
|
8
|
+
|
9
|
+
subject { described_class.new(-> (_) {}, environment) }
|
10
|
+
|
11
|
+
describe '#call' do
|
12
|
+
|
13
|
+
before{allow(env[:machine].provider).to receive(:state).and_return(Vagrant::MachineState.new nil, nil, nil)}
|
14
|
+
|
15
|
+
it_behaves_like 'a proxmox action call'
|
16
|
+
|
17
|
+
context 'when the machine is stopped' do
|
18
|
+
before do
|
19
|
+
allow(env[:machine].provider).to receive(:state).and_return(Vagrant::MachineState.new :stopped, '', '')
|
20
|
+
subject.call env
|
21
|
+
end
|
22
|
+
specify { env[:result].should == true }
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'when the machine is not created' do
|
26
|
+
before do
|
27
|
+
allow(env[:machine].provider).to receive(:state).and_return(Vagrant::MachineState.new :not_created, '', '')
|
28
|
+
subject.call env
|
29
|
+
end
|
30
|
+
specify { env[:result].should == false }
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'actions/proxmox_action_shared'
|
3
|
+
|
4
|
+
describe VagrantPlugins::Proxmox::Action::IsStopped do
|
5
|
+
|
6
|
+
let(:environment) { Vagrant::Environment.new vagrantfile_name: 'dummy_box/Vagrantfile' }
|
7
|
+
let(:env) { {machine: environment.machine(environment.primary_machine_name, :proxmox)} }
|
8
|
+
|
9
|
+
subject { described_class.new(-> (_) {}, environment) }
|
10
|
+
|
11
|
+
describe '#call' do
|
12
|
+
|
13
|
+
before { allow(env[:machine].provider).to receive(:state).and_return(Vagrant::MachineState.new nil, nil, nil) }
|
14
|
+
|
15
|
+
it_behaves_like 'a proxmox action call'
|
16
|
+
|
17
|
+
context 'when the machine is stopped' do
|
18
|
+
before do
|
19
|
+
allow(env[:machine].provider).to receive(:state).and_return(Vagrant::MachineState.new :stopped, '', '')
|
20
|
+
subject.call env
|
21
|
+
end
|
22
|
+
specify { env[:result].should == true }
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'when the machine is running' do
|
26
|
+
before do
|
27
|
+
allow(env[:machine].provider).to receive(:state).and_return(Vagrant::MachineState.new :running, '', '')
|
28
|
+
subject.call env
|
29
|
+
end
|
30
|
+
specify { env[:result].should == false }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'actions/proxmox_action_shared'
|
3
|
+
|
4
|
+
describe VagrantPlugins::Proxmox::Action::MessageAlreadyRunning do
|
5
|
+
|
6
|
+
let(:environment) { Vagrant::Environment.new vagrantfile_name: 'dummy_box/Vagrantfile' }
|
7
|
+
let(:env) { {ui: double('ui').as_null_object} }
|
8
|
+
|
9
|
+
subject { described_class.new(-> (_) {}, environment) }
|
10
|
+
|
11
|
+
before { VagrantPlugins::Proxmox::Plugin.setup_i18n }
|
12
|
+
|
13
|
+
describe '#call' do
|
14
|
+
|
15
|
+
it_behaves_like 'a proxmox action call'
|
16
|
+
|
17
|
+
specify do
|
18
|
+
expect(env[:ui]).to receive(:info).with 'The virtual machine is already up and running'
|
19
|
+
subject.call env
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'actions/proxmox_action_shared'
|
3
|
+
|
4
|
+
describe VagrantPlugins::Proxmox::Action::MessageAlreadyStopped do
|
5
|
+
|
6
|
+
let(:environment) { Vagrant::Environment.new vagrantfile_name: 'dummy_box/Vagrantfile' }
|
7
|
+
let(:env) { {ui: double('ui').as_null_object} }
|
8
|
+
|
9
|
+
subject { described_class.new(-> (_) {}, environment) }
|
10
|
+
|
11
|
+
before { VagrantPlugins::Proxmox::Plugin.setup_i18n }
|
12
|
+
|
13
|
+
describe '#call' do
|
14
|
+
|
15
|
+
it_behaves_like 'a proxmox action call'
|
16
|
+
|
17
|
+
specify do
|
18
|
+
expect(env[:ui]).to receive(:info).with 'The virtual machine is already stopped'
|
19
|
+
subject.call env
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'actions/proxmox_action_shared'
|
3
|
+
|
4
|
+
describe VagrantPlugins::Proxmox::Action::MessageNotCreated do
|
5
|
+
|
6
|
+
let(:environment) { Vagrant::Environment.new vagrantfile_name: 'dummy_box/Vagrantfile' }
|
7
|
+
let(:env) { {ui: double('ui').as_null_object} }
|
8
|
+
|
9
|
+
subject { described_class.new(-> (_) {}, environment) }
|
10
|
+
|
11
|
+
before { VagrantPlugins::Proxmox::Plugin.setup_i18n }
|
12
|
+
|
13
|
+
describe '#call' do
|
14
|
+
|
15
|
+
it_behaves_like 'a proxmox action call'
|
16
|
+
|
17
|
+
specify do
|
18
|
+
expect(env[:ui]).to receive(:info).with 'The virtual machine is not created on the server!'
|
19
|
+
subject.call env
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
shared_examples VagrantPlugins::Proxmox::Action::ProxmoxAction do
|
2
|
+
|
3
|
+
let(:environment) { Vagrant::Environment.new vagrantfile_name: 'dummy_box/Vagrantfile'}
|
4
|
+
let(:env) { {machine: environment.machine(environment.primary_machine_name, :proxmox),
|
5
|
+
proxmox_nodes: [{node: 'localhost'}]} }
|
6
|
+
let(:task_upid) { 'UPID:localhost:0000F6ED:00F8E25F:5268CD3B:vzcreate:100:vagrant@pve:' }
|
7
|
+
|
8
|
+
describe '#wait_for_completion' do
|
9
|
+
|
10
|
+
context 'when the task is completed' do
|
11
|
+
before { allow(subject).to receive(:get_task_exitstatus).and_return('OK') }
|
12
|
+
it 'should return the tasks exit status' do
|
13
|
+
subject.send(:wait_for_completion, task_upid, 'localhost', env, '').should == 'OK'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'when the task times out' do
|
18
|
+
before do
|
19
|
+
allow(subject).to receive(:get_task_exitstatus).and_return(nil)
|
20
|
+
Retryable.disable
|
21
|
+
end
|
22
|
+
it 'should raise an timeout error' do
|
23
|
+
expect { subject.send(:wait_for_completion, task_upid, 'localhost', env, '') }.to raise_error VagrantPlugins::Proxmox::Errors::Timeout
|
24
|
+
end
|
25
|
+
after { Retryable.enable }
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#get_task_exitstatus' do
|
31
|
+
|
32
|
+
it 'should request the task state from the proxmox server' do
|
33
|
+
RestClient.should_receive(:get).with("https://your.proxmox.server/api2/json/nodes/localhost/tasks/#{task_upid}/status", anything).
|
34
|
+
and_return({data: {}}.to_json)
|
35
|
+
subject.send(:get_task_exitstatus, task_upid, 'localhost', env)
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'the task has exited' do
|
39
|
+
it 'should return the exit status' do
|
40
|
+
allow(RestClient).to receive(:get).and_return({data: {upid: task_upid, status: 'stopped', exitstatus: 'OK'}}.to_json)
|
41
|
+
subject.send(:get_task_exitstatus, task_upid, 'localhost', env).should == 'OK'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'the task is still running' do
|
46
|
+
it 'should return nil' do
|
47
|
+
allow(RestClient).to receive(:get).and_return({data: {upid: task_upid, status: 'running'}}.to_json)
|
48
|
+
subject.send(:get_task_exitstatus, task_upid, 'localhost', env).should == nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
shared_examples 'a proxmox action call' do
|
57
|
+
|
58
|
+
describe 'when done' do
|
59
|
+
it 'should call the next action' do
|
60
|
+
expect(subject).to receive(:next_action).with env
|
61
|
+
subject.call env
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
shared_examples 'a blocking proxmox action' do
|
68
|
+
|
69
|
+
it 'waits for completion of the server task' do
|
70
|
+
subject.should receive(:wait_for_completion)
|
71
|
+
subject.call env
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'actions/proxmox_action_shared'
|
3
|
+
|
4
|
+
describe VagrantPlugins::Proxmox::Action::ReadSSHInfo do
|
5
|
+
|
6
|
+
let(:environment) { Vagrant::Environment.new vagrantfile_name: 'dummy_box/Vagrantfile' }
|
7
|
+
let(:env) { {machine: environment.machine(environment.primary_machine_name, :proxmox)} }
|
8
|
+
|
9
|
+
subject { described_class.new(-> (_) {}, environment) }
|
10
|
+
|
11
|
+
describe '#call' do
|
12
|
+
|
13
|
+
it_behaves_like 'a proxmox action call'
|
14
|
+
|
15
|
+
context 'when no ip address is configured' do
|
16
|
+
it 'should write no ssh info into env[:machine_ssh_info]' do
|
17
|
+
subject.call env
|
18
|
+
env[:machine_ssh_info].should == nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'when an ip address is configured' do
|
23
|
+
before { env[:machine].config.vm.stub(:networks) { [[:public_network, {ip: '127.0.0.1'}]] } }
|
24
|
+
it 'should write the ssh info into env[:machine_ssh_info]' do
|
25
|
+
subject.call env
|
26
|
+
env[:machine_ssh_info].should == {host: '127.0.0.1', port: 22}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'actions/proxmox_action_shared'
|
3
|
+
|
4
|
+
describe VagrantPlugins::Proxmox::Action::ReadState do
|
5
|
+
|
6
|
+
let(:environment) { Vagrant::Environment.new vagrantfile_name: 'dummy_box/Vagrantfile' }
|
7
|
+
let(:env) { {machine: environment.machine(environment.primary_machine_name, :proxmox)} }
|
8
|
+
|
9
|
+
subject { described_class.new(-> (_) {}, environment) }
|
10
|
+
|
11
|
+
describe '#call' do
|
12
|
+
|
13
|
+
it_behaves_like 'a proxmox action call'
|
14
|
+
|
15
|
+
context 'when no machine id is defined' do
|
16
|
+
specify do
|
17
|
+
subject.call env
|
18
|
+
env[:machine_state_id].should == :not_created
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'when the machine is not created' do
|
23
|
+
before { env[:machine].id = 'localhost/100' }
|
24
|
+
specify do
|
25
|
+
RestClient.should_receive(:get).with('https://your.proxmox.server/api2/json/nodes/localhost/openvz/100/status/current', anything).
|
26
|
+
and_raise(RestClient::InternalServerError)
|
27
|
+
subject.call env
|
28
|
+
env[:machine_state_id].should == :not_created
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'when the machine is stopped' do
|
33
|
+
before { env[:machine].id = 'localhost/100' }
|
34
|
+
specify do
|
35
|
+
RestClient.should_receive(:get).with('https://your.proxmox.server/api2/json/nodes/localhost/openvz/100/status/current', anything).
|
36
|
+
and_return({data: {status: 'stopped'}}.to_json)
|
37
|
+
subject.call env
|
38
|
+
env[:machine_state_id].should == :stopped
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'when the machine is running' do
|
43
|
+
before { env[:machine].id = 'localhost/100' }
|
44
|
+
specify do
|
45
|
+
RestClient.should_receive(:get).with('https://your.proxmox.server/api2/json/nodes/localhost/openvz/100/status/current', anything).
|
46
|
+
and_return({data: {status: 'running'}}.to_json)
|
47
|
+
subject.call env
|
48
|
+
env[:machine_state_id].should == :running
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'actions/proxmox_action_shared'
|
3
|
+
|
4
|
+
describe VagrantPlugins::Proxmox::Action::ShutdownVm do
|
5
|
+
|
6
|
+
let(:environment) { Vagrant::Environment.new vagrantfile_name: 'dummy_box/Vagrantfile' }
|
7
|
+
let(:env) { {machine: environment.machine(environment.primary_machine_name, :proxmox),
|
8
|
+
proxmox_nodes: [{node: 'localhost'}],
|
9
|
+
ui: double('ui').as_null_object} }
|
10
|
+
|
11
|
+
subject { described_class.new(-> (_) {}, environment) }
|
12
|
+
|
13
|
+
describe '#call' do
|
14
|
+
|
15
|
+
before do
|
16
|
+
env[:machine].id = 'localhost/100'
|
17
|
+
allow(RestClient).to receive(:post).and_return({data: 'task_id'}.to_json)
|
18
|
+
allow(RestClient).to receive(:get).and_return({data: {exitstatus: 'OK'}}.to_json)
|
19
|
+
end
|
20
|
+
|
21
|
+
it_behaves_like 'a proxmox action call'
|
22
|
+
it_behaves_like 'a blocking proxmox action'
|
23
|
+
|
24
|
+
it 'should send a post request that shuts down the openvz container' do
|
25
|
+
RestClient.should_receive(:post).with('https://your.proxmox.server/api2/json/nodes/localhost/openvz/100/status/shutdown', nil, anything)
|
26
|
+
subject.call env
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should print a message to the user interface' do
|
30
|
+
env[:ui].should_receive(:info).with 'Shutting down the virtual machine...'
|
31
|
+
env[:ui].should_receive(:info).with 'Done!'
|
32
|
+
subject.call env
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'actions/proxmox_action_shared'
|
3
|
+
|
4
|
+
describe VagrantPlugins::Proxmox::Action::StartVm do
|
5
|
+
|
6
|
+
let(:environment) { Vagrant::Environment.new vagrantfile_name: 'dummy_box/Vagrantfile' }
|
7
|
+
let(:env) { {machine: environment.machine(environment.primary_machine_name, :proxmox),
|
8
|
+
proxmox_nodes: [{node: 'localhost'}],
|
9
|
+
ui: double('ui').as_null_object} }
|
10
|
+
|
11
|
+
subject { described_class.new(-> (_) {}, environment) }
|
12
|
+
|
13
|
+
describe '#call' do
|
14
|
+
|
15
|
+
before do
|
16
|
+
env[:machine].id = 'localhost/100'
|
17
|
+
allow(RestClient).to receive(:post).and_return({data: 'task_id'}.to_json)
|
18
|
+
allow(RestClient).to receive(:get).and_return({data: {exitstatus: 'OK'}}.to_json)
|
19
|
+
allow(env[:machine].communicate).to receive(:ready?).and_return true
|
20
|
+
end
|
21
|
+
|
22
|
+
it_behaves_like 'a proxmox action call'
|
23
|
+
it_behaves_like 'a blocking proxmox action'
|
24
|
+
|
25
|
+
it 'should send a post request that starts the openvz container' do
|
26
|
+
RestClient.should_receive(:post).with('https://your.proxmox.server/api2/json/nodes/localhost/openvz/100/status/start', nil, anything)
|
27
|
+
subject.call env
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should print a message to the user interface' do
|
31
|
+
env[:ui].should_receive(:info).with 'Starting the virtual machine...'
|
32
|
+
env[:ui].should_receive(:info).with 'Done!'
|
33
|
+
env[:ui].should_receive(:info).with 'Waiting for SSH connection...'
|
34
|
+
env[:ui].should_receive(:info).with 'Done!'
|
35
|
+
subject.call env
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should periodically call env[:machine].communicate.ready? to check for ssh access' do
|
39
|
+
expect(env[:machine].communicate).to receive(:ready?).and_return false
|
40
|
+
expect(subject).to receive(:sleep).with 1
|
41
|
+
expect(env[:machine].communicate).to receive(:ready?).and_return true
|
42
|
+
subject.call env
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'actions/proxmox_action_shared'
|
3
|
+
|
4
|
+
describe VagrantPlugins::Proxmox::Action::StopVm do
|
5
|
+
|
6
|
+
let(:environment) { Vagrant::Environment.new vagrantfile_name: 'dummy_box/Vagrantfile' }
|
7
|
+
let(:env) { {machine: environment.machine(environment.primary_machine_name, :proxmox),
|
8
|
+
proxmox_nodes: [{node: 'localhost'}],
|
9
|
+
ui: double('ui').as_null_object} }
|
10
|
+
|
11
|
+
subject { described_class.new(-> (_) {}, environment) }
|
12
|
+
|
13
|
+
describe '#call' do
|
14
|
+
|
15
|
+
before do
|
16
|
+
env[:machine].id = 'localhost/100'
|
17
|
+
allow(RestClient).to receive(:post).and_return({data: 'task_id'}.to_json)
|
18
|
+
allow(RestClient).to receive(:get).and_return({data: {exitstatus: 'OK'}}.to_json)
|
19
|
+
end
|
20
|
+
|
21
|
+
it_behaves_like 'a proxmox action call'
|
22
|
+
it_behaves_like 'a blocking proxmox action'
|
23
|
+
|
24
|
+
it 'should send a post request that stops the openvz container' do
|
25
|
+
RestClient.should_receive(:post).with('https://your.proxmox.server/api2/json/nodes/localhost/openvz/100/status/stop', nil, anything)
|
26
|
+
subject.call env
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should print a message to the user interface' do
|
30
|
+
env[:ui].should_receive(:info).with 'Stopping the virtual machine...'
|
31
|
+
env[:ui].should_receive(:info).with 'Done!'
|
32
|
+
subject.call env
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|