vcloud-launcher 0.1.0 → 0.2.0
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.
- data/.gitignore +1 -0
- data/.travis.yml +2 -0
- data/CHANGELOG.md +13 -0
- data/CONTRIBUTING.md +66 -0
- data/Gemfile +2 -2
- data/Rakefile +3 -9
- data/bin/vcloud-launch +1 -44
- data/lib/vcloud/launcher.rb +2 -0
- data/lib/vcloud/launcher/cli.rb +103 -0
- data/lib/vcloud/launcher/launch.rb +36 -1
- data/lib/vcloud/launcher/preamble.rb +60 -0
- data/lib/vcloud/launcher/version.rb +1 -1
- data/lib/vcloud/launcher/vm_orchestrator.rb +10 -5
- data/spec/integration/README.md +1 -1
- data/spec/integration/launcher/data/storage_profile.yaml.erb +0 -30
- data/spec/integration/launcher/{vcloud_launcher_spec.rb → launch_spec.rb} +42 -31
- data/spec/integration/launcher/storage_profile_integration_spec.rb +23 -35
- data/spec/spec_helper.rb +29 -0
- data/spec/vcloud/launcher/cli_spec.rb +214 -0
- data/spec/vcloud/launcher/launch_spec.rb +107 -1
- data/spec/vcloud/launcher/preamble_spec.rb +214 -0
- data/spec/vcloud/launcher/vapp_orchestrator_spec.rb +14 -14
- data/spec/vcloud/launcher/vm_orchestrator_spec.rb +109 -22
- data/vcloud-launcher.gemspec +8 -8
- metadata +40 -71
- data/features/step_definitions/vcloud-launch_steps.rb +0 -3
- data/features/support/env.rb +0 -16
- data/features/vcloud-launch.feature +0 -18
@@ -68,7 +68,113 @@ describe Vcloud::Launcher::Launch do
|
|
68
68
|
expect(Vcloud::Core.logger).to receive(:level=).with(Logger::INFO)
|
69
69
|
subject.set_logging_level({})
|
70
70
|
end
|
71
|
-
|
72
71
|
end
|
73
72
|
|
73
|
+
describe "configuration validation" do
|
74
|
+
let(:config_file) { 'foo' }
|
75
|
+
|
76
|
+
before(:each) do
|
77
|
+
Vcloud::Core::ConfigLoader.any_instance.stub(:load_config).and_return(config)
|
78
|
+
|
79
|
+
allow(Vcloud::Launcher::VappOrchestrator).
|
80
|
+
to receive(:provision).and_return(double(:vapp, :power_on => true))
|
81
|
+
end
|
82
|
+
|
83
|
+
subject { Vcloud::Launcher::Launch.new }
|
84
|
+
|
85
|
+
context "when bootstrap configuration is supplied" do
|
86
|
+
context "script_path is missing" do
|
87
|
+
let(:config) do
|
88
|
+
{ vapps: [
|
89
|
+
{
|
90
|
+
name: "test_vapp_name",
|
91
|
+
vdc_name: "Test VDC",
|
92
|
+
catalog_name: "default",
|
93
|
+
vapp_template_name: "ubuntu-precise",
|
94
|
+
bootstrap: {
|
95
|
+
vars: { foo: 'bar' }
|
96
|
+
}
|
97
|
+
}
|
98
|
+
]
|
99
|
+
}
|
100
|
+
end
|
101
|
+
|
102
|
+
it "raises MissingConfigurationError" do
|
103
|
+
expect{ subject.run(config_file) }.
|
104
|
+
to raise_error(Vcloud::Launcher::Launch::MissingConfigurationError)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context "script_path does not exist" do
|
109
|
+
let(:config) do
|
110
|
+
{ vapps: [
|
111
|
+
{
|
112
|
+
name: "test_vapp_name",
|
113
|
+
vdc_name: "Test VDC",
|
114
|
+
catalog_name: "default",
|
115
|
+
vapp_template_name: "ubuntu-precise",
|
116
|
+
bootstrap: {
|
117
|
+
script_path: 'nonexistent_preamble.sh.erb',
|
118
|
+
vars: { foo: 'bar' }
|
119
|
+
}
|
120
|
+
}
|
121
|
+
]
|
122
|
+
}
|
123
|
+
end
|
124
|
+
|
125
|
+
it "raises MissingPreambleError" do
|
126
|
+
expect{ subject.run(config_file) }.
|
127
|
+
to raise_error(Vcloud::Launcher::Launch::MissingPreambleError)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context "script_path is specified, without vars" do
|
132
|
+
# Avoid triggering exceptions on missing preamble file.
|
133
|
+
before do
|
134
|
+
File.stub(:exist?).and_return(true)
|
135
|
+
allow(Vcloud::Core.logger).to receive(:info)
|
136
|
+
end
|
137
|
+
|
138
|
+
let(:config) do
|
139
|
+
{ vapps: [
|
140
|
+
{
|
141
|
+
name: "test_vapp_name",
|
142
|
+
vdc_name: "Test VDC",
|
143
|
+
catalog_name: "default",
|
144
|
+
vapp_template_name: "ubuntu-precise",
|
145
|
+
bootstrap: {
|
146
|
+
script_path: 'nonexistent_preamble.sh.erb'
|
147
|
+
}
|
148
|
+
}
|
149
|
+
]
|
150
|
+
}
|
151
|
+
end
|
152
|
+
|
153
|
+
it "logs an informative message" do
|
154
|
+
# A rather overly specific test to find the message of
|
155
|
+
# interest amongst other log messages.
|
156
|
+
expect(Vcloud::Core.logger).to receive(:info).with(/without variables to template/)
|
157
|
+
subject.run(config_file)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
context "when bootstrap configuration is absent" do
|
163
|
+
let(:config) do
|
164
|
+
{ vapps: [
|
165
|
+
{
|
166
|
+
name: "test_vapp_name",
|
167
|
+
vdc_name: "Test VDC",
|
168
|
+
catalog_name: "default",
|
169
|
+
vapp_template_name: "ubuntu-precise"
|
170
|
+
}
|
171
|
+
]
|
172
|
+
}
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should not raise an error" do
|
176
|
+
expect{ subject.run(config_file) }.not_to raise_error
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
74
180
|
end
|
@@ -0,0 +1,214 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Vcloud
|
4
|
+
module Launcher
|
5
|
+
describe Preamble do
|
6
|
+
subject { Vcloud::Launcher::Preamble }
|
7
|
+
|
8
|
+
let(:vm_name) { 'test-vm' }
|
9
|
+
let(:minimal_vm_config) do
|
10
|
+
{ bootstrap: {
|
11
|
+
script_path: 'hello_world.erb',
|
12
|
+
vars: { bob: 'Hello', mary: 'Hola' }
|
13
|
+
}
|
14
|
+
}
|
15
|
+
end
|
16
|
+
let(:minimal_template) do
|
17
|
+
<<-'EOF'
|
18
|
+
vars:
|
19
|
+
bob: <%= vars[:bob] -%>.
|
20
|
+
mary: <%= vars[:mary] %>.
|
21
|
+
EOF
|
22
|
+
end
|
23
|
+
let(:minimal_template_output) do
|
24
|
+
<<-EOF
|
25
|
+
vars:
|
26
|
+
bob: Hello.
|
27
|
+
mary: Hola.
|
28
|
+
EOF
|
29
|
+
end
|
30
|
+
let(:minimal_template_lines) { 3 }
|
31
|
+
|
32
|
+
let(:complete_vm_config) do
|
33
|
+
{ bootstrap: {
|
34
|
+
script_path: 'hello_world.erb',
|
35
|
+
script_post_processor: '/usr/bin/wc -l',
|
36
|
+
vars: { bob: 'Hello', mary: 'Hola' }
|
37
|
+
},
|
38
|
+
extra_disks: [
|
39
|
+
{ size: 5120, fs_file: '/opt/test_disk1' },
|
40
|
+
{ size: 10240, fs_file: '/opt/test_disk2' },
|
41
|
+
]
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
describe 'public interface' do
|
46
|
+
describe 'instance methods' do
|
47
|
+
subject { Vcloud::Launcher::Preamble.new(vm_name, minimal_vm_config) }
|
48
|
+
|
49
|
+
it { should respond_to(:generate) }
|
50
|
+
it { should respond_to(:interpolated_preamble) }
|
51
|
+
|
52
|
+
it { should respond_to(:preamble_vars) }
|
53
|
+
it { should respond_to(:script_path) }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '#new' do
|
58
|
+
it "accepts complete configuration without error" do
|
59
|
+
expect { subject.new(vm_name, minimal_vm_config) }.not_to raise_error
|
60
|
+
end
|
61
|
+
|
62
|
+
context "when the preamble template is missing" do
|
63
|
+
let(:vm_config) do
|
64
|
+
{ bootstrap: {
|
65
|
+
script_post_processor: 'remove_hello.rb',
|
66
|
+
vars: { bob: 'hello', mary: 'hola' }
|
67
|
+
}
|
68
|
+
}
|
69
|
+
end
|
70
|
+
|
71
|
+
it "raises a MissingTemplateError" do
|
72
|
+
expect { subject.new(vm_name, vm_config) }.
|
73
|
+
to raise_error( Vcloud::Launcher::Preamble::MissingTemplateError)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "when bootstrap configuration is empty" do
|
78
|
+
it "raises a MissingConfigurationError" do
|
79
|
+
expect { subject.new(vm_name, {}) }.
|
80
|
+
to raise_error(Vcloud::Launcher::Preamble::MissingConfigurationError)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context "when vars are absent" do
|
85
|
+
let(:vm_config) do
|
86
|
+
{ bootstrap: {
|
87
|
+
script_path: 'hello_world.erb',
|
88
|
+
script_post_processor: 'remove_hello.rb'
|
89
|
+
},
|
90
|
+
}
|
91
|
+
end
|
92
|
+
|
93
|
+
it "does not raise an error (allows for post-processing only)" do
|
94
|
+
expect { subject.new(vm_name, vm_config ) }.not_to raise_error
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context "when vars are empty" do
|
99
|
+
let(:vm_config) do
|
100
|
+
{ bootstrap: {
|
101
|
+
script_path: 'hello_world.erb',
|
102
|
+
script_post_processor: 'remove_hello.rb',
|
103
|
+
vars: {},
|
104
|
+
}
|
105
|
+
}
|
106
|
+
end
|
107
|
+
|
108
|
+
it "raises a MissingConfigurationError (allows for post-processing only)" do
|
109
|
+
expect { subject.new(vm_name, vm_config ) }.not_to raise_error
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context "extra_disks" do
|
114
|
+
subject { Vcloud::Launcher::Preamble.new(vm_name, complete_vm_config) }
|
115
|
+
|
116
|
+
it "merges extra_disks into preamble_vars" do
|
117
|
+
expect( subject.preamble_vars ).to have_key(:extra_disks)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
describe ".generate" do
|
123
|
+
subject { Vcloud::Launcher::Preamble.new(vm_name, minimal_vm_config) }
|
124
|
+
|
125
|
+
before(:each) do
|
126
|
+
subject.stub(:load_erb_file).and_return(minimal_template)
|
127
|
+
end
|
128
|
+
|
129
|
+
it "invokes .interpolate_preamble_erb_file" do
|
130
|
+
subject.should_receive(:interpolate_erb_file)
|
131
|
+
subject.generate
|
132
|
+
end
|
133
|
+
|
134
|
+
context "interpolating variables" do
|
135
|
+
subject { Vcloud::Launcher::Preamble.new(vm_name, minimal_vm_config) }
|
136
|
+
|
137
|
+
context "environment variables" do
|
138
|
+
before(:each) do
|
139
|
+
stub_const('ENV', {'TEST_INTERPOLATED_ENVVAR' => 'test_interpolated_env'})
|
140
|
+
subject.stub(:load_erb_file).and_return('env_var: <%= ENV["TEST_INTERPOLATED_ENVVAR"] -%>')
|
141
|
+
end
|
142
|
+
|
143
|
+
it "interpolates environment variables into template" do
|
144
|
+
expect(subject.generate).to eq 'env_var: test_interpolated_env'
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context "vars hash" do
|
149
|
+
before(:each) do
|
150
|
+
subject.stub(:load_erb_file).and_return(minimal_template)
|
151
|
+
end
|
152
|
+
|
153
|
+
it "interpolates vars hash into template" do
|
154
|
+
expect(subject.generate).to eq minimal_template_output
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
context "vapp_name" do
|
159
|
+
before(:each) do
|
160
|
+
subject.stub(:load_erb_file).and_return('vapp_name: <%= vapp_name -%>')
|
161
|
+
end
|
162
|
+
|
163
|
+
it "interpolates vapp_name into template" do
|
164
|
+
expect(subject.generate).to eq "vapp_name: #{vm_name}"
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context "when a post processor is supplied" do
|
170
|
+
let(:vm_config) do
|
171
|
+
{ bootstrap: {
|
172
|
+
script_path: 'hello_world.erb',
|
173
|
+
script_post_processor: '/usr/bin/wc -l',
|
174
|
+
vars: { bob: 'hello', mary: 'hola' }
|
175
|
+
}
|
176
|
+
}
|
177
|
+
end
|
178
|
+
|
179
|
+
let(:template) do
|
180
|
+
<<-EOF
|
181
|
+
one
|
182
|
+
two
|
183
|
+
three
|
184
|
+
EOF
|
185
|
+
end
|
186
|
+
|
187
|
+
subject { Vcloud::Launcher::Preamble.new(vm_name, vm_config) }
|
188
|
+
|
189
|
+
before(:each) do
|
190
|
+
subject.stub(:load_erb_file).and_return(template)
|
191
|
+
end
|
192
|
+
|
193
|
+
it "invokes .post_process_erb_output" do
|
194
|
+
subject.should_receive(:post_process_erb_output)
|
195
|
+
subject.generate
|
196
|
+
end
|
197
|
+
|
198
|
+
it "returns the post-processed interpolated template" do
|
199
|
+
expect(subject.generate).to match(/\s*#{minimal_template_lines}/)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
describe ".interpolated_preamble" do
|
204
|
+
subject { Vcloud::Launcher::Preamble.new(vm_name, minimal_vm_config) }
|
205
|
+
|
206
|
+
it "returns the interpolated template" do
|
207
|
+
expect(subject.interpolated_preamble).to eq minimal_template_output
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
@@ -31,25 +31,25 @@ describe Vcloud::Launcher::VappOrchestrator do
|
|
31
31
|
it "should return a vapp if it already exists" do
|
32
32
|
existing_vapp = double(:vapp, :name => 'existing-vapp-1')
|
33
33
|
|
34
|
-
Vcloud::Core::Vapp.
|
35
|
-
Vcloud::Core.logger.
|
34
|
+
expect(Vcloud::Core::Vapp).to receive(:get_by_name_and_vdc_name).with('test-vapp-1', 'test-vdc-1').and_return(existing_vapp)
|
35
|
+
expect(Vcloud::Core.logger).to receive(:info).with('Found existing vApp test-vapp-1 in vDC \'test-vdc-1\'. Skipping.')
|
36
36
|
actual_vapp = subject.provision @config
|
37
|
-
actual_vapp.
|
38
|
-
actual_vapp.
|
37
|
+
expect(actual_vapp).not_to be_nil
|
38
|
+
expect(actual_vapp).to eq(existing_vapp)
|
39
39
|
end
|
40
40
|
|
41
41
|
it "should create a vapp if it does not exist" do
|
42
42
|
#this test highlights the problems in vapp
|
43
43
|
|
44
|
-
Vcloud::Core::Vapp.
|
45
|
-
Vcloud::Core::VappTemplate.
|
44
|
+
expect(Vcloud::Core::Vapp).to receive(:get_by_name_and_vdc_name).with('test-vapp-1', 'test-vdc-1').and_return(nil)
|
45
|
+
expect(Vcloud::Core::VappTemplate).to receive(:get).with('org-1-template', 'org-1-catalog').and_return(double(:vapp_template, :id => 1))
|
46
46
|
|
47
|
-
Vcloud::Core::Vapp.
|
47
|
+
expect(Vcloud::Core::Vapp).to receive(:instantiate).with('test-vapp-1', ['org-vdc-1-net-1'], 1, 'test-vdc-1')
|
48
48
|
.and_return(mock_vapp)
|
49
|
-
Vcloud::Launcher::VmOrchestrator.
|
49
|
+
expect(Vcloud::Launcher::VmOrchestrator).to receive(:new).with(mock_fog_vm, mock_vapp).and_return(mock_vm_orchestrator)
|
50
50
|
|
51
51
|
new_vapp = subject.provision @config
|
52
|
-
new_vapp.
|
52
|
+
expect(new_vapp).to eq(mock_vapp)
|
53
53
|
end
|
54
54
|
|
55
55
|
context "deprecated config items" do
|
@@ -57,9 +57,9 @@ describe Vcloud::Launcher::VappOrchestrator do
|
|
57
57
|
double(:vapp_template, :id => 2)
|
58
58
|
}
|
59
59
|
before(:each) {
|
60
|
-
Vcloud::Core::Vapp.
|
61
|
-
Vcloud::Core::Vapp.
|
62
|
-
Vcloud::Launcher::VmOrchestrator.
|
60
|
+
allow(Vcloud::Core::Vapp).to receive(:get_by_name_and_vdc_name)
|
61
|
+
allow(Vcloud::Core::Vapp).to receive(:instantiate).and_return(mock_vapp)
|
62
|
+
allow(Vcloud::Launcher::VmOrchestrator).to receive(:new).and_return(mock_vm_orchestrator)
|
63
63
|
}
|
64
64
|
|
65
65
|
it "should use catalog_item when vapp_template_name is not present" do
|
@@ -67,7 +67,7 @@ describe Vcloud::Launcher::VappOrchestrator do
|
|
67
67
|
config.delete(:vapp_template_name)
|
68
68
|
config[:catalog_item] = 'deprecated-template'
|
69
69
|
|
70
|
-
Vcloud::Core::VappTemplate.
|
70
|
+
expect(Vcloud::Core::VappTemplate).to receive(:get).with('deprecated-template', 'org-1-catalog').and_return(mock_vapp_template)
|
71
71
|
Vcloud::Launcher::VappOrchestrator.provision(config)
|
72
72
|
end
|
73
73
|
|
@@ -76,7 +76,7 @@ describe Vcloud::Launcher::VappOrchestrator do
|
|
76
76
|
config.delete(:catalog_name)
|
77
77
|
config[:catalog] = 'deprecated-catalog'
|
78
78
|
|
79
|
-
Vcloud::Core::VappTemplate.
|
79
|
+
expect(Vcloud::Core::VappTemplate).to receive(:get).with('org-1-template', 'deprecated-catalog').and_return(mock_vapp_template)
|
80
80
|
Vcloud::Launcher::VappOrchestrator.provision(config)
|
81
81
|
end
|
82
82
|
end
|
@@ -16,7 +16,7 @@ describe Vcloud::Launcher::VmOrchestrator do
|
|
16
16
|
Vcloud::Launcher::VmOrchestrator.new(fog_vm, vapp)
|
17
17
|
}
|
18
18
|
|
19
|
-
it "
|
19
|
+
it "orchestrates customization" do
|
20
20
|
vm_config = {
|
21
21
|
:hardware_config => {
|
22
22
|
:memory => 4096,
|
@@ -33,28 +33,23 @@ describe Vcloud::Launcher::VmOrchestrator do
|
|
33
33
|
:network_connections => [
|
34
34
|
{:name => "network1", :ip_address => "198.12.1.21"},
|
35
35
|
],
|
36
|
-
:bootstrap => {
|
37
|
-
:script_path => '/tmp/boostrap.erb',
|
38
|
-
:vars => {
|
39
|
-
:message => 'hello world'
|
40
|
-
}
|
41
|
-
},
|
42
36
|
:storage_profile => {
|
43
37
|
:name => 'basic-storage',
|
44
38
|
:href => 'https://vcloud.example.net/api/vdcStorageProfile/000aea1e-a5e9-4dd1-a028-40db8c98d237'
|
45
39
|
}
|
46
40
|
}
|
47
41
|
vm = double(:vm, :id => @vm_id, :vapp_name => 'web-app1', :vapp => vapp, :name => 'test-vm-1')
|
48
|
-
Vcloud::Core::Vm.
|
42
|
+
expect(Vcloud::Core::Vm).to receive(:new).with(@vm_id, vapp).and_return(vm)
|
43
|
+
|
44
|
+
expect(vm).to receive(:update_name).with('web-app1')
|
45
|
+
expect(vm).to receive(:configure_network_interfaces).with(vm_config[:network_connections])
|
46
|
+
expect(vm).to receive(:update_storage_profile).with(vm_config[:storage_profile])
|
47
|
+
expect(vm).to receive(:update_cpu_count).with(2)
|
48
|
+
expect(vm).to receive(:update_memory_size_in_mb).with(4096)
|
49
|
+
expect(vm).to receive(:add_extra_disks).with(vm_config[:extra_disks])
|
50
|
+
expect(vm).to receive(:update_metadata).with(vm_config[:metadata])
|
49
51
|
|
50
|
-
vm.
|
51
|
-
vm.should_receive(:configure_network_interfaces).with(vm_config[:network_connections])
|
52
|
-
vm.should_receive(:update_storage_profile).with(vm_config[:storage_profile])
|
53
|
-
vm.should_receive(:update_cpu_count).with(2)
|
54
|
-
vm.should_receive(:update_memory_size_in_mb).with(4096)
|
55
|
-
vm.should_receive(:add_extra_disks).with(vm_config[:extra_disks])
|
56
|
-
vm.should_receive(:update_metadata).with(vm_config[:metadata])
|
57
|
-
vm.should_receive(:configure_guest_customization_section).with('web-app1', vm_config[:bootstrap], vm_config[:extra_disks])
|
52
|
+
allow(vm).to receive(:configure_guest_customization_section).with('')
|
58
53
|
|
59
54
|
subject.customize(vm_config)
|
60
55
|
end
|
@@ -69,14 +64,106 @@ describe Vcloud::Launcher::VmOrchestrator do
|
|
69
64
|
{:size => '2048', :name => 'Hard disk 3', :fs_file => 'solr', :fs_mntops => 'solr-something'}
|
70
65
|
]
|
71
66
|
}
|
72
|
-
Vcloud::Core::Vm.
|
73
|
-
vm.
|
74
|
-
vm.
|
75
|
-
vm.
|
76
|
-
vm.
|
77
|
-
|
67
|
+
expect(Vcloud::Core::Vm).to receive(:new).with(@vm_id, vapp).and_return(vm)
|
68
|
+
expect(vm).to receive(:update_metadata).with(:shutdown => true)
|
69
|
+
expect(vm).to receive(:update_name).with('web-app1')
|
70
|
+
expect(vm).to receive(:add_extra_disks).with(vm_config[:extra_disks])
|
71
|
+
expect(vm).to receive(:configure_network_interfaces).with(vm_config[:network_connections])
|
72
|
+
|
73
|
+
allow(vm).to receive(:configure_guest_customization_section)
|
78
74
|
|
79
75
|
subject.customize(vm_config)
|
76
|
+
end
|
77
|
+
|
78
|
+
context "when customizing a VM" do
|
79
|
+
let(:vm_config_with_bootstrap) do
|
80
|
+
{
|
81
|
+
hardware_config: {
|
82
|
+
memory: 4096,
|
83
|
+
cpu: 2
|
84
|
+
},
|
85
|
+
network_connections: [
|
86
|
+
{ name: "network1", ip_address: "198.12.1.21" }
|
87
|
+
],
|
88
|
+
bootstrap: {
|
89
|
+
script_path: '/tmp/bootstrap.erb',
|
90
|
+
vars: { message: 'hello world' }
|
91
|
+
}
|
92
|
+
}
|
93
|
+
end
|
94
|
+
|
95
|
+
let(:vm_config_without_bootstrap) do
|
96
|
+
{
|
97
|
+
hardware_config: {
|
98
|
+
memory: 4096,
|
99
|
+
cpu: 2
|
100
|
+
},
|
101
|
+
network_connections: [
|
102
|
+
{ name: "network1", ip_address: "198.12.1.21" }
|
103
|
+
]
|
104
|
+
}
|
105
|
+
end
|
106
|
+
|
107
|
+
let(:vm) { double(:vm, id: @vm_id, vapp_name: 'web-app1', vapp: vapp, name: 'test-vm-1') }
|
108
|
+
|
109
|
+
before(:each) do
|
110
|
+
Vcloud::Core::Vm.stub(:new).and_return(vm)
|
111
|
+
allow(vm).to receive(:update_name)
|
112
|
+
allow(vm).to receive(:configure_network_interfaces)
|
113
|
+
allow(vm).to receive(:update_cpu_count)
|
114
|
+
allow(vm).to receive(:update_memory_size_in_mb)
|
115
|
+
allow(vm).to receive(:add_extra_disks)
|
116
|
+
allow(vm).to receive(:update_metadata)
|
117
|
+
end
|
118
|
+
|
119
|
+
context "when bootstrap configuration is omitted" do
|
120
|
+
before { allow(vm).to receive(:configure_guest_customization_section) }
|
121
|
+
|
122
|
+
it "skips preamble processing" do
|
123
|
+
expect(Vcloud::Launcher::Preamble).not_to receive(:new)
|
124
|
+
expect(Vcloud::Launcher::Preamble).not_to receive(:generate)
|
125
|
+
|
126
|
+
subject.customize(vm_config_without_bootstrap)
|
127
|
+
end
|
128
|
+
|
129
|
+
it "uses an empty string as the host preamble" do
|
130
|
+
expect(vm).to receive(:configure_guest_customization_section).with('')
|
131
|
+
subject.customize(vm_config_without_bootstrap)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context "when bootstrap configuration is supplied" do
|
136
|
+
context "Vcloud::Launcher::Preamble used to generate a preamble" do
|
137
|
+
it "instantiates Vcloud::Launcher::Preamble" do
|
138
|
+
preamble = double
|
139
|
+
allow(preamble).to receive(:generate)
|
140
|
+
allow(vm).to receive(:configure_guest_customization_section)
|
141
|
+
|
142
|
+
expect(Vcloud::Launcher::Preamble).to receive(:new).with(vm.vapp_name, vm_config_with_bootstrap).and_return(preamble)
|
143
|
+
|
144
|
+
subject.customize(vm_config_with_bootstrap)
|
145
|
+
end
|
146
|
+
|
147
|
+
it "uses Vcloud::Launcher::Preamble.generate to template a preamble" do
|
148
|
+
preamble = double
|
149
|
+
allow(Vcloud::Launcher::Preamble).to receive(:new).with(vm.vapp_name, vm_config_with_bootstrap).and_return(preamble)
|
150
|
+
allow(vm).to receive(:configure_guest_customization_section)
|
151
|
+
|
152
|
+
expect(preamble).to receive(:generate)
|
153
|
+
|
154
|
+
subject.customize(vm_config_with_bootstrap)
|
155
|
+
end
|
156
|
+
|
157
|
+
it "passes the generated preamble to configure_guest_customization_section" do
|
158
|
+
preamble = double
|
159
|
+
allow(Vcloud::Launcher::Preamble).to receive(:new).with(vm.vapp_name, vm_config_with_bootstrap).and_return(preamble)
|
160
|
+
allow(preamble).to receive(:generate).and_return('FAKE_PREAMBLE')
|
161
|
+
|
162
|
+
expect(vm).to receive(:configure_guest_customization_section).with('FAKE_PREAMBLE')
|
80
163
|
|
164
|
+
subject.customize(vm_config_with_bootstrap)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
81
168
|
end
|
82
169
|
end
|