vagrant-proxmox 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/lib/sanity_checks.rb +11 -0
  3. data/lib/vagrant-proxmox/action/cleanup_after_destroy.rb +20 -0
  4. data/lib/vagrant-proxmox/action/connect_proxmox.rb +33 -0
  5. data/lib/vagrant-proxmox/action/create_vm.rb +63 -0
  6. data/lib/vagrant-proxmox/action/destroy_vm.rb +29 -0
  7. data/lib/vagrant-proxmox/action/get_node_list.rb +24 -0
  8. data/lib/vagrant-proxmox/action/is_created.rb +20 -0
  9. data/lib/vagrant-proxmox/action/is_stopped.rb +20 -0
  10. data/lib/vagrant-proxmox/action/message_already_running.rb +20 -0
  11. data/lib/vagrant-proxmox/action/message_already_stopped.rb +20 -0
  12. data/lib/vagrant-proxmox/action/message_not_created.rb +20 -0
  13. data/lib/vagrant-proxmox/action/proxmox_action.rb +47 -0
  14. data/lib/vagrant-proxmox/action/read_ssh_info.rb +22 -0
  15. data/lib/vagrant-proxmox/action/read_state.rb +37 -0
  16. data/lib/vagrant-proxmox/action/shutdown_vm.rb +31 -0
  17. data/lib/vagrant-proxmox/action/start_vm.rb +40 -0
  18. data/lib/vagrant-proxmox/action/stop_vm.rb +31 -0
  19. data/lib/vagrant-proxmox/action/sync_folders.rb +52 -0
  20. data/lib/vagrant-proxmox/action.rb +159 -0
  21. data/lib/vagrant-proxmox/config.rb +81 -0
  22. data/lib/vagrant-proxmox/errors.rb +39 -0
  23. data/lib/vagrant-proxmox/plugin.rb +75 -0
  24. data/lib/vagrant-proxmox/provider.rb +51 -0
  25. data/lib/vagrant-proxmox/version.rb +7 -0
  26. data/lib/vagrant-proxmox.rb +22 -0
  27. data/locales/en.yml +66 -0
  28. data/spec/actions/cleanup_after_destroy_action_spec.rb +22 -0
  29. data/spec/actions/connect_proxmox_action_spec.rb +49 -0
  30. data/spec/actions/create_vm_action_spec.rb +167 -0
  31. data/spec/actions/destroy_vm_action_spec.rb +37 -0
  32. data/spec/actions/get_node_list_action_spec.rb +25 -0
  33. data/spec/actions/is_created_action_spec.rb +35 -0
  34. data/spec/actions/is_stopped_action_spec.rb +34 -0
  35. data/spec/actions/message_already_running_action_spec.rb +23 -0
  36. data/spec/actions/message_already_stopped_action_spec.rb +23 -0
  37. data/spec/actions/message_not_created_action_spec.rb +23 -0
  38. data/spec/actions/proxmox_action_shared.rb +74 -0
  39. data/spec/actions/read_ssh_info_action_spec.rb +32 -0
  40. data/spec/actions/read_state_action_spec.rb +54 -0
  41. data/spec/actions/shutdown_vm_action_spec.rb +37 -0
  42. data/spec/actions/start_vm_action_spec.rb +47 -0
  43. data/spec/actions/stop_vm_action_spec.rb +37 -0
  44. data/spec/actions/sync_folders_action_spec.rb +51 -0
  45. data/spec/commands/destroy_command_spec.rb +68 -0
  46. data/spec/commands/halt_command_spec.rb +46 -0
  47. data/spec/commands/provision_command_spec.rb +33 -0
  48. data/spec/commands/ssh_command_spec.rb +31 -0
  49. data/spec/commands/ssh_run_command_spec.rb +32 -0
  50. data/spec/commands/status_command_spec.rb +19 -0
  51. data/spec/commands/up_command_spec.rb +55 -0
  52. data/spec/config_spec.rb +71 -0
  53. data/spec/plugin_spec.rb +22 -0
  54. data/spec/provider_spec.rb +25 -0
  55. data/spec/sanity_checks_spec.rb +19 -0
  56. data/spec/spec_helper.rb +128 -0
  57. 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