vagrant-proxmox 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|